]> git.saurik.com Git - apple/ld64.git/commitdiff
ld64-84.1.2.tar.gz iphone-20 v84.1.2
authorApple <opensource@apple.com>
Tue, 1 Jul 2008 21:06:59 +0000 (21:06 +0000)
committerApple <opensource@apple.com>
Tue, 1 Jul 2008 21:06:59 +0000 (21:06 +0000)
630 files changed:
APPLE_LICENSE [changed mode: 0644->0755]
ChangeLog [changed mode: 0644->0755]
doc/man/man1/ld.1 [changed mode: 0644->0755]
doc/man/man1/ld64.1 [changed mode: 0644->0755]
doc/man/man1/rebase.1 [changed mode: 0644->0755]
ld64.xcodeproj/project.pbxproj [changed mode: 0644->0755]
src/Architectures.hpp [changed mode: 0644->0755]
src/ArchiveReader.hpp [new file with mode: 0755]
src/ExecutableFile.h [changed mode: 0644->0755]
src/FileAbstraction.hpp [changed mode: 0644->0755]
src/LLVMReader.hpp [deleted file]
src/LTOReader.hpp [new file with mode: 0755]
src/MachOFileAbstraction.hpp [changed mode: 0644->0755]
src/MachOReaderArchive.hpp [deleted file]
src/MachOReaderDylib.hpp [changed mode: 0644->0755]
src/MachOReaderRelocatable.hpp [changed mode: 0644->0755]
src/MachOWriterExecutable.hpp [changed mode: 0644->0755]
src/ObjectDump.cpp [changed mode: 0644->0755]
src/ObjectFile.h [changed mode: 0644->0755]
src/OpaqueSection.hpp [changed mode: 0644->0755]
src/Options.cpp [changed mode: 0644->0755]
src/Options.h [changed mode: 0644->0755]
src/SectCreate.h [changed mode: 0644->0755]
src/debugline.c [changed mode: 0644->0755]
src/debugline.h [changed mode: 0644->0755]
src/dwarf2.h [changed mode: 0644->0755]
src/ld.cpp [changed mode: 0644->0755]
src/machochecker.cpp [changed mode: 0644->0755]
src/rebase.cpp [changed mode: 0644->0755]
unit-tests/README [changed mode: 0644->0755]
unit-tests/include/common.makefile [changed mode: 0644->0755]
unit-tests/include/test.h [changed mode: 0644->0755]
unit-tests/run-all-unit-tests
unit-tests/src/Makefile [changed mode: 0644->0755]
unit-tests/src/results-to-xml.cpp [changed mode: 0644->0755]
unit-tests/src/xmlparser/xmlparser.1 [changed mode: 0644->0755]
unit-tests/src/xmlparser/xmlparser.m [changed mode: 0644->0755]
unit-tests/src/xmlparser/xmlparser.xcodeproj/project.pbxproj [changed mode: 0644->0755]
unit-tests/src/xmlparser/xmlparser_Prefix.pch [changed mode: 0644->0755]
unit-tests/test-cases/16-byte-alignment/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/16-byte-alignment/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/16-byte-alignment/tl_test2.c [changed mode: 0644->0755]
unit-tests/test-cases/absolute-symbol/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/absolute-symbol/abs.s [changed mode: 0644->0755]
unit-tests/test-cases/absolute-symbol/main.c [changed mode: 0644->0755]
unit-tests/test-cases/alias-command-line/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/alias-command-line/aliases.s [changed mode: 0644->0755]
unit-tests/test-cases/alias-command-line/aliases.txt [changed mode: 0644->0755]
unit-tests/test-cases/alias-objects/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/alias-objects/aliases.s [changed mode: 0644->0755]
unit-tests/test-cases/align-modulus/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/align-modulus/align.s [changed mode: 0644->0755]
unit-tests/test-cases/align-modulus/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/align-modulus/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/align-modulus/foo.exp [changed mode: 0644->0755]
unit-tests/test-cases/allow-stack-execute/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/allow-stack-execute/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/allow-stack-execute/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/allowable-client/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/allowable-client/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/allowable-client/baz.c [changed mode: 0644->0755]
unit-tests/test-cases/allowable-client/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/allowable-client/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/allowable-client/main.c [changed mode: 0644->0755]
unit-tests/test-cases/archive-ObjC/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/archive-ObjC/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/archive-ObjC/baz.m [changed mode: 0644->0755]
unit-tests/test-cases/archive-ObjC/foo.m [changed mode: 0644->0755]
unit-tests/test-cases/archive-ObjC/main.c [changed mode: 0644->0755]
unit-tests/test-cases/archive-basic/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/archive-basic/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/archive-basic/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/archive-basic/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/archive-basic/main.c [changed mode: 0644->0755]
unit-tests/test-cases/archive-duplicate/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/archive-duplicate/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/archive-duplicate/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/archive-duplicate/main.c [changed mode: 0644->0755]
unit-tests/test-cases/archive-weak/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/archive-weak/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/archive-weak/baz.c [changed mode: 0644->0755]
unit-tests/test-cases/archive-weak/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/archive-weak/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/archive-weak/main.c [changed mode: 0644->0755]
unit-tests/test-cases/auto-arch/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/auto-arch/hello.c [changed mode: 0644->0755]
unit-tests/test-cases/auto-arch2/Makefile [deleted file]
unit-tests/test-cases/auto-arch2/comment.txt [deleted file]
unit-tests/test-cases/auto-arch2/hello.c [deleted file]
unit-tests/test-cases/blank-stubs/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/blank-stubs/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/blank-stubs/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/blank-stubs/main.c [changed mode: 0644->0755]
unit-tests/test-cases/bundle_loader/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/bundle_loader/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/bundle_loader/bundle.c [changed mode: 0644->0755]
unit-tests/test-cases/bundle_loader/comment.txt [deleted file]
unit-tests/test-cases/bundle_loader/main.c [changed mode: 0644->0755]
unit-tests/test-cases/cfstring-coalesce/Makefile [new file with mode: 0755]
unit-tests/test-cases/cfstring-coalesce/bar.c [new file with mode: 0755]
unit-tests/test-cases/cfstring-coalesce/foo.c [new file with mode: 0755]
unit-tests/test-cases/cfstring-utf16/Makefile [new file with mode: 0755]
unit-tests/test-cases/cfstring-utf16/bar.m [new file with mode: 0755]
unit-tests/test-cases/cfstring-utf16/foo.m [new file with mode: 0755]
unit-tests/test-cases/commons-alignment/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/commons-alignment/foo.s [changed mode: 0644->0755]
unit-tests/test-cases/commons-coalesced-dead_strip/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/commons-coalesced-dead_strip/a.c [changed mode: 0644->0755]
unit-tests/test-cases/commons-coalesced-dead_strip/b.c [changed mode: 0644->0755]
unit-tests/test-cases/commons-coalesced-dead_strip/c.c [changed mode: 0644->0755]
unit-tests/test-cases/commons-coalesced-dead_strip/c.h [changed mode: 0644->0755]
unit-tests/test-cases/commons-mixed/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/commons-mixed/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/commons-mixed/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/commons-order/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/commons-order/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/commons-order/baz.c [changed mode: 0644->0755]
unit-tests/test-cases/commons-order/expected.order [changed mode: 0644->0755]
unit-tests/test-cases/commons-order/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/commons-order/main.c [changed mode: 0644->0755]
unit-tests/test-cases/cpu-sub-types-preference/Makefile [new file with mode: 0755]
unit-tests/test-cases/cpu-sub-types-preference/foo.c [new file with mode: 0755]
unit-tests/test-cases/cpu-sub-types/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/cpu-sub-types/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/cpu-sub-types/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/cpu-sub-types/main.c [changed mode: 0644->0755]
unit-tests/test-cases/dead_strip-archive-global/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/dead_strip-archive-global/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/dead_strip-archive-global/main.c [changed mode: 0644->0755]
unit-tests/test-cases/dead_strip-archive/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/dead_strip-archive/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/dead_strip-archive/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/dead_strip-archive/main.c [changed mode: 0644->0755]
unit-tests/test-cases/dead_strip-init-archive/Makefile [new file with mode: 0755]
unit-tests/test-cases/dead_strip-init-archive/bar.c [new file with mode: 0755]
unit-tests/test-cases/dead_strip-init-archive/foo.c [new file with mode: 0755]
unit-tests/test-cases/dead_strip/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/dead_strip/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/dead_strip/deadwood.c [changed mode: 0644->0755]
unit-tests/test-cases/dead_strip/main.c [changed mode: 0644->0755]
unit-tests/test-cases/dead_strip/main.exp [changed mode: 0644->0755]
unit-tests/test-cases/dead_strip_dylibs/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/dead_strip_dylibs/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/dead_strip_dylibs/baz.c [changed mode: 0644->0755]
unit-tests/test-cases/dead_strip_dylibs/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/dead_strip_dylibs/main.c [changed mode: 0644->0755]
unit-tests/test-cases/dead_strip_section_attribute/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/dead_strip_section_attribute/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/dead_strip_section_attribute/main.c [changed mode: 0644->0755]
unit-tests/test-cases/dtrace-static-probes-coalescing/Makefile [new file with mode: 0755]
unit-tests/test-cases/dtrace-static-probes-coalescing/Number.d [new file with mode: 0755]
unit-tests/test-cases/dtrace-static-probes-coalescing/a.cxx [new file with mode: 0755]
unit-tests/test-cases/dtrace-static-probes-coalescing/header.h [new file with mode: 0755]
unit-tests/test-cases/dtrace-static-probes-coalescing/x.cxx [new file with mode: 0755]
unit-tests/test-cases/dtrace-static-probes/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/dtrace-static-probes/bar.d [changed mode: 0644->0755]
unit-tests/test-cases/dtrace-static-probes/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/dtrace-static-probes/foo.d [changed mode: 0644->0755]
unit-tests/test-cases/dtrace-static-probes/main.c [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-archive-all_load/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-archive-all_load/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-archive-all_load/baz.c [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-archive-all_load/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-archive-all_load/expected-stabs [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-archive-all_load/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-debug-notes-r/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-debug-notes-r/bar.cxx [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-debug-notes-r/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-debug-notes-r/expected-stabs [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-debug-notes-r/foo.cxx [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-debug-notes-r/main.cxx [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-debug-notes/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-debug-notes/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-debug-notes/expected-stabs [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-debug-notes/header.h [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-debug-notes/hello.cxx [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-debug-notes/other.cxx [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-ignore/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-ignore/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-ignore/hello.c [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-strip/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-strip/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/dwarf-strip/hello.c [changed mode: 0644->0755]
unit-tests/test-cases/dylib-aliases/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/dylib-aliases/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/dylib-aliases/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/dylib-aliases/main.c [changed mode: 0644->0755]
unit-tests/test-cases/dylib-re-export-cycle/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/dylib-re-export-cycle/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/dylib-re-export-cycle/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/dylib-re-export-cycle/main.c [changed mode: 0644->0755]
unit-tests/test-cases/dylib_file-missing/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/dylib_file-missing/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/dylib_file-missing/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/dylib_file-missing/main.c [changed mode: 0644->0755]
unit-tests/test-cases/dylib_file/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/dylib_file/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/dylib_file/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/dylib_file/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/dylib_file/main.c [changed mode: 0644->0755]
unit-tests/test-cases/dylib_init/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/dylib_init/comment.txt [deleted file]
unit-tests/test-cases/dylib_init/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/eh-coalescing-r/Makefile [new file with mode: 0755]
unit-tests/test-cases/eh-coalescing-r/bar.cxx [new file with mode: 0755]
unit-tests/test-cases/eh-coalescing-r/foo.cxx [new file with mode: 0755]
unit-tests/test-cases/eh-coalescing-r/func.h [new file with mode: 0755]
unit-tests/test-cases/eh-coalescing/Makefile [new file with mode: 0755]
unit-tests/test-cases/eh-coalescing/bar.cxx [new file with mode: 0755]
unit-tests/test-cases/eh-coalescing/foo.cxx [new file with mode: 0755]
unit-tests/test-cases/eh-coalescing/foo2.cxx [new file with mode: 0755]
unit-tests/test-cases/eh-coalescing/func.h [new file with mode: 0755]
unit-tests/test-cases/eh-strip-test/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/eh-strip-test/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/eh-strip-test/main.cxx [changed mode: 0644->0755]
unit-tests/test-cases/eh_frame/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/eh_frame/bar.cxx [changed mode: 0644->0755]
unit-tests/test-cases/eh_frame/foo.cxx [changed mode: 0644->0755]
unit-tests/test-cases/empty-object/Makefile [new file with mode: 0755]
unit-tests/test-cases/empty-object/main.c [new file with mode: 0755]
unit-tests/test-cases/end-label/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/end-label/bar.s [changed mode: 0644->0755]
unit-tests/test-cases/end-label/foo.s [changed mode: 0644->0755]
unit-tests/test-cases/exported-symbols-wildcards-dead_strip/Makefile [new file with mode: 0755]
unit-tests/test-cases/exported-symbols-wildcards-dead_strip/foo.c [new file with mode: 0755]
unit-tests/test-cases/exported-symbols-wildcards/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/exported-symbols-wildcards/expect1 [changed mode: 0644->0755]
unit-tests/test-cases/exported-symbols-wildcards/expect2 [changed mode: 0644->0755]
unit-tests/test-cases/exported-symbols-wildcards/expect3 [changed mode: 0644->0755]
unit-tests/test-cases/exported-symbols-wildcards/expect4 [changed mode: 0644->0755]
unit-tests/test-cases/exported-symbols-wildcards/expect5 [changed mode: 0644->0755]
unit-tests/test-cases/exported-symbols-wildcards/expect6 [changed mode: 0644->0755]
unit-tests/test-cases/exported-symbols-wildcards/expect7 [changed mode: 0644->0755]
unit-tests/test-cases/exported-symbols-wildcards/expect8 [changed mode: 0644->0755]
unit-tests/test-cases/exported-symbols-wildcards/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/exported-symbols-wildcards/list5 [changed mode: 0644->0755]
unit-tests/test-cases/exported_symbols_list-eol/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/exported_symbols_list-eol/expected.nm [changed mode: 0644->0755]
unit-tests/test-cases/exported_symbols_list-eol/test.c [changed mode: 0644->0755]
unit-tests/test-cases/exported_symbols_list-eol/test.exp [changed mode: 0644->0755]
unit-tests/test-cases/exported_symbols_list-hidden/Makefile [new file with mode: 0755]
unit-tests/test-cases/exported_symbols_list-hidden/test.c [new file with mode: 0755]
unit-tests/test-cases/exported_symbols_list-hidden/test.exp [new file with mode: 0755]
unit-tests/test-cases/exported_symbols_list-r/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/exported_symbols_list-r/test-bad.exp [changed mode: 0644->0755]
unit-tests/test-cases/exported_symbols_list-r/test.c [changed mode: 0644->0755]
unit-tests/test-cases/exported_symbols_list-r/test.exp [changed mode: 0644->0755]
unit-tests/test-cases/external-reloc-sorting/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/external-reloc-sorting/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/external-reloc-sorting/main.c [changed mode: 0644->0755]
unit-tests/test-cases/filelist/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/filelist/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/filelist/hello.c [changed mode: 0644->0755]
unit-tests/test-cases/flat-dylib/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/flat-dylib/main.c [changed mode: 0644->0755]
unit-tests/test-cases/flat-indirect-undefines/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/flat-indirect-undefines/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/flat-indirect-undefines/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/flat-indirect-undefines/main.c [changed mode: 0644->0755]
unit-tests/test-cases/flat-main/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/flat-main/main.c [changed mode: 0644->0755]
unit-tests/test-cases/got-elimination/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/got-elimination/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/got-elimination/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/header-pad/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/header-pad/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/header-pad/hello.c [changed mode: 0644->0755]
unit-tests/test-cases/hello-world/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/hello-world/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/hello-world/hello.c [changed mode: 0644->0755]
unit-tests/test-cases/implicit-common2/Makefile.newtest [changed mode: 0644->0755]
unit-tests/test-cases/implicit-common2/a.c [changed mode: 0644->0755]
unit-tests/test-cases/implicit-common2/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/implicit-common2/test.c [changed mode: 0644->0755]
unit-tests/test-cases/implicit-common3/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/implicit-common3/a.c [changed mode: 0644->0755]
unit-tests/test-cases/implicit-common3/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/implicit-common3/test.c [changed mode: 0644->0755]
unit-tests/test-cases/implicit-common4/Makefile.newtest [changed mode: 0644->0755]
unit-tests/test-cases/implicit-common4/a.c [changed mode: 0644->0755]
unit-tests/test-cases/implicit-common4/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/implicit-common4/test.c [changed mode: 0644->0755]
unit-tests/test-cases/implicit-common5/Makefile.newtest [changed mode: 0644->0755]
unit-tests/test-cases/implicit-common5/a.c [changed mode: 0644->0755]
unit-tests/test-cases/implicit-common5/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/implicit-common5/test.c [changed mode: 0644->0755]
unit-tests/test-cases/implicit_dylib/Makefile [new file with mode: 0755]
unit-tests/test-cases/implicit_dylib/bar.c [new file with mode: 0755]
unit-tests/test-cases/implicit_dylib/foo.c [new file with mode: 0755]
unit-tests/test-cases/implicit_dylib/main.c [new file with mode: 0755]
unit-tests/test-cases/indirect-dylib/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/indirect-dylib/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/indirect-dylib/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/indirect-dylib/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/indirect-dylib/main.c [changed mode: 0644->0755]
unit-tests/test-cases/indirect-path-search/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/indirect-path-search/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/indirect-path-search/baz.c [changed mode: 0644->0755]
unit-tests/test-cases/indirect-path-search/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/indirect-path-search/main.c [changed mode: 0644->0755]
unit-tests/test-cases/interposable_list/Makefile [new file with mode: 0755]
unit-tests/test-cases/interposable_list/test.c [new file with mode: 0755]
unit-tests/test-cases/interposable_list/test.exp [new file with mode: 0755]
unit-tests/test-cases/large-data/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/large-data/test1.c [changed mode: 0644->0755]
unit-tests/test-cases/large-data/test2.c [changed mode: 0644->0755]
unit-tests/test-cases/large-data/test3.c [changed mode: 0644->0755]
unit-tests/test-cases/large-data/test4.c [changed mode: 0644->0755]
unit-tests/test-cases/late-link-error/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/late-link-error/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/late-link-error/link_error.s [changed mode: 0644->0755]
unit-tests/test-cases/lazy-dylib-objc/Makefile [new file with mode: 0755]
unit-tests/test-cases/lazy-dylib-objc/foo.h [new file with mode: 0755]
unit-tests/test-cases/lazy-dylib-objc/foo.m [new file with mode: 0755]
unit-tests/test-cases/lazy-dylib-objc/main.m [new file with mode: 0755]
unit-tests/test-cases/lazy-dylib/Makefile [new file with mode: 0755]
unit-tests/test-cases/lazy-dylib/bad.c [new file with mode: 0755]
unit-tests/test-cases/lazy-dylib/bad2.c [new file with mode: 0755]
unit-tests/test-cases/lazy-dylib/foo.c [new file with mode: 0755]
unit-tests/test-cases/lazy-dylib/main.c [new file with mode: 0755]
unit-tests/test-cases/literals-coalesce-alignment/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/literals-coalesce-alignment/cstring-align-0.s [changed mode: 0644->0755]
unit-tests/test-cases/literals-coalesce-alignment/cstring-align-3.s [changed mode: 0644->0755]
unit-tests/test-cases/literals-coalesce-alignment2/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/literals-coalesce-alignment2/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/literals-coalesce-alignment2/cstring-align-0.s [changed mode: 0644->0755]
unit-tests/test-cases/literals-coalesce-alignment2/cstring-align-3.s [changed mode: 0644->0755]
unit-tests/test-cases/literals-coalesce-alignment3/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/literals-coalesce-alignment3/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/literals-coalesce-alignment3/cstring-align-0.s [changed mode: 0644->0755]
unit-tests/test-cases/literals-coalesce-alignment3/cstring-align-3.s [changed mode: 0644->0755]
unit-tests/test-cases/literals-coalesce/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/literals-coalesce/literals.s [changed mode: 0644->0755]
unit-tests/test-cases/literals-coalesce2/Makefile.newtest [changed mode: 0644->0755]
unit-tests/test-cases/literals-coalesce2/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/literals-coalesce2/literals.s [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/a.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/a1.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/a10.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/a11.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/a12.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/a12.h [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/a13.cc [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/a13.h [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/a14.c [new file with mode: 0755]
unit-tests/test-cases/llvm-integration/a15.c [new file with mode: 0755]
unit-tests/test-cases/llvm-integration/a17.c [new file with mode: 0755]
unit-tests/test-cases/llvm-integration/a18.c [new file with mode: 0755]
unit-tests/test-cases/llvm-integration/a2.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/a20.c [new file with mode: 0755]
unit-tests/test-cases/llvm-integration/a3.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/a4.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/a5.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/a6.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/a7.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/a8.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/a9.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/a9.list [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/b.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/b1.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/b10.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/b10.h [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/b14.c [new file with mode: 0755]
unit-tests/test-cases/llvm-integration/b15.c [new file with mode: 0755]
unit-tests/test-cases/llvm-integration/b17.c [new file with mode: 0755]
unit-tests/test-cases/llvm-integration/b2.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/b20.c [new file with mode: 0755]
unit-tests/test-cases/llvm-integration/b3.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/b4.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/b5.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/b7.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/c15.c [new file with mode: 0755]
unit-tests/test-cases/llvm-integration/main.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/main1.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/main10.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/main11.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/main12.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/main13.cc [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/main16.c [new file with mode: 0755]
unit-tests/test-cases/llvm-integration/main19.c [new file with mode: 0755]
unit-tests/test-cases/llvm-integration/main2.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/main20.c [new file with mode: 0755]
unit-tests/test-cases/llvm-integration/main3.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/main4.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/main5.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/main6.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/main7.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/main8.c [changed mode: 0644->0755]
unit-tests/test-cases/llvm-integration/main9.c [changed mode: 0644->0755]
unit-tests/test-cases/loader_path/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/loader_path/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/loader_path/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/loader_path/main.c [changed mode: 0644->0755]
unit-tests/test-cases/local-symbol-partial-stripping/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/local-symbol-partial-stripping/a.expect [changed mode: 0644->0755]
unit-tests/test-cases/local-symbol-partial-stripping/a.list [changed mode: 0644->0755]
unit-tests/test-cases/local-symbol-partial-stripping/b.expect [changed mode: 0644->0755]
unit-tests/test-cases/local-symbol-partial-stripping/b.list [changed mode: 0644->0755]
unit-tests/test-cases/local-symbol-partial-stripping/c.list [changed mode: 0644->0755]
unit-tests/test-cases/local-symbol-partial-stripping/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/local-symbol-partial-stripping/main.c [changed mode: 0644->0755]
unit-tests/test-cases/main-stripped/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/main-stripped/main.c [changed mode: 0644->0755]
unit-tests/test-cases/main-stripped/main.exp [changed mode: 0644->0755]
unit-tests/test-cases/missing-option-args/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/missing-option-args/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/multiple-entry-points/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/multiple-entry-points/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/multiple-entry-points/test.s [changed mode: 0644->0755]
unit-tests/test-cases/no-dynamic-common/Makefile.newtest [changed mode: 0644->0755]
unit-tests/test-cases/no-dynamic-common/a.c [changed mode: 0644->0755]
unit-tests/test-cases/no-dynamic-common/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/no-dynamic-common/test.c [changed mode: 0644->0755]
unit-tests/test-cases/no-uuid/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/no-uuid/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/no-uuid/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/no-uuid/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/non-lazy-r/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/non-lazy-r/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/non-lazy-r/other.c [changed mode: 0644->0755]
unit-tests/test-cases/objc-category-debug-notes/Makefile [new file with mode: 0755]
unit-tests/test-cases/objc-category-debug-notes/test.m [new file with mode: 0755]
unit-tests/test-cases/objc-exported_symbols_list/Makefile [new file with mode: 0755]
unit-tests/test-cases/objc-exported_symbols_list/foo.exp [new file with mode: 0755]
unit-tests/test-cases/objc-exported_symbols_list/foo.m [new file with mode: 0755]
unit-tests/test-cases/objc-gc-checks/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/objc-gc-checks/bar.m [changed mode: 0644->0755]
unit-tests/test-cases/objc-gc-checks/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/objc-gc-checks/foo.m [changed mode: 0644->0755]
unit-tests/test-cases/objc-gc-checks/runtime.c [new file with mode: 0755]
unit-tests/test-cases/objc-literal-pointers/Makefile [new file with mode: 0755]
unit-tests/test-cases/objc-literal-pointers/test.m [new file with mode: 0755]
unit-tests/test-cases/objc-references/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/objc-references/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/objc-references/test.m [changed mode: 0644->0755]
unit-tests/test-cases/objc-selector-coalescing/Makefile [new file with mode: 0755]
unit-tests/test-cases/objc-selector-coalescing/main.m [new file with mode: 0755]
unit-tests/test-cases/objc-selector-coalescing/other.m [new file with mode: 0755]
unit-tests/test-cases/operator-new/Makefile [new file with mode: 0755]
unit-tests/test-cases/operator-new/main.cxx [new file with mode: 0755]
unit-tests/test-cases/order_file-ans/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/order_file-ans/main.cxx [changed mode: 0644->0755]
unit-tests/test-cases/order_file-ans/main.expected [changed mode: 0644->0755]
unit-tests/test-cases/order_file-ans/main.order [changed mode: 0644->0755]
unit-tests/test-cases/order_file/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/order_file/extra.s [changed mode: 0644->0755]
unit-tests/test-cases/order_file/main.c [changed mode: 0644->0755]
unit-tests/test-cases/order_file/main1.expected [changed mode: 0644->0755]
unit-tests/test-cases/order_file/main1.order [changed mode: 0644->0755]
unit-tests/test-cases/order_file/main2.expected [changed mode: 0644->0755]
unit-tests/test-cases/order_file/main2.order [changed mode: 0644->0755]
unit-tests/test-cases/order_file/main3.expected [changed mode: 0644->0755]
unit-tests/test-cases/order_file/main3.order [changed mode: 0644->0755]
unit-tests/test-cases/prebound-main/Makefile [new file with mode: 0755]
unit-tests/test-cases/prebound-main/main.c [new file with mode: 0755]
unit-tests/test-cases/prebound-split-seg/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/prebound-split-seg/address_table [changed mode: 0644->0755]
unit-tests/test-cases/prebound-split-seg/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/private-non-lazy/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/private-non-lazy/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/private-non-lazy/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/private-non-lazy/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/private-non-lazy/hello.c [changed mode: 0644->0755]
unit-tests/test-cases/re-export-cases/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/re-export-cases/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/re-export-cases/baz.c [changed mode: 0644->0755]
unit-tests/test-cases/re-export-cases/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/re-export-flag/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/re-export-flag/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/re-export-flag/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/re-export-optimizations/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/re-export-optimizations/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/re-export-optimizations/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/re-export-optimizations/main.c [changed mode: 0644->0755]
unit-tests/test-cases/re-export-relative-paths/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/re-export-relative-paths/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/re-export-relative-paths/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/re-export-relative-paths/main.c [changed mode: 0644->0755]
unit-tests/test-cases/re-export-relative-paths/wrap.c [changed mode: 0644->0755]
unit-tests/test-cases/read-only-relocs/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/read-only-relocs/comment.txt [deleted file]
unit-tests/test-cases/read-only-relocs/foo.c [new file with mode: 0755]
unit-tests/test-cases/read-only-relocs/test.c [changed mode: 0644->0755]
unit-tests/test-cases/rebase-basic/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/rebase-basic/bar.m [changed mode: 0644->0755]
unit-tests/test-cases/rebase-basic/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/rebase-basic/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/relocs-asm/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/relocs-asm/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/relocs-asm/relocs-asm.s [changed mode: 0644->0755]
unit-tests/test-cases/relocs-c/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/relocs-c/test.c [changed mode: 0644->0755]
unit-tests/test-cases/relocs-c2/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/relocs-c2/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/relocs-c2/test.c [changed mode: 0644->0755]
unit-tests/test-cases/relocs-literals/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/relocs-literals/test.c [changed mode: 0644->0755]
unit-tests/test-cases/relocs-literals2/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/relocs-literals2/test.c [changed mode: 0644->0755]
unit-tests/test-cases/relocs-literals3/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/relocs-literals3/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/relocs-literals3/test.c [changed mode: 0644->0755]
unit-tests/test-cases/relocs-objc/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/relocs-objc/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/relocs-objc/test.m [changed mode: 0644->0755]
unit-tests/test-cases/segment-order/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/segment-order/expected.order [changed mode: 0644->0755]
unit-tests/test-cases/segment-order/main.c [changed mode: 0644->0755]
unit-tests/test-cases/segment-order/segJJJ.s [changed mode: 0644->0755]
unit-tests/test-cases/segment-order/segKKK.s [changed mode: 0644->0755]
unit-tests/test-cases/segment-order/segLLL.s [changed mode: 0644->0755]
unit-tests/test-cases/slow-x86-stubs/Makefile [new file with mode: 0755]
unit-tests/test-cases/slow-x86-stubs/hello.c [new file with mode: 0755]
unit-tests/test-cases/special-labels/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/special-labels/extra.s [changed mode: 0644->0755]
unit-tests/test-cases/special-labels/main.c [changed mode: 0644->0755]
unit-tests/test-cases/stabs-coalesce/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/stabs-coalesce/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/stabs-coalesce/header.h [changed mode: 0644->0755]
unit-tests/test-cases/stabs-coalesce/hello.cxx [changed mode: 0644->0755]
unit-tests/test-cases/stabs-coalesce/other.cxx [changed mode: 0644->0755]
unit-tests/test-cases/stabs-directory-slash/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/stabs-directory-slash/main.c [changed mode: 0644->0755]
unit-tests/test-cases/stack_addr_no_size/Makefile.newtest [changed mode: 0644->0755]
unit-tests/test-cases/stack_addr_no_size/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/stack_addr_no_size/main.c [changed mode: 0644->0755]
unit-tests/test-cases/stack_addr_size/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/stack_addr_size/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/stack_addr_size/main.c [changed mode: 0644->0755]
unit-tests/test-cases/stack_size_no_addr/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/stack_size_no_addr/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/stack_size_no_addr/main.c [changed mode: 0644->0755]
unit-tests/test-cases/static-executable/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/static-executable/comment.txt [deleted file]
unit-tests/test-cases/static-executable/test.c [changed mode: 0644->0755]
unit-tests/test-cases/static-strip/Makefile.newtest [changed mode: 0644->0755]
unit-tests/test-cases/static-strip/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/static-strip/test.c [changed mode: 0644->0755]
unit-tests/test-cases/strip-test2/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/strip-test2/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/strip-test2/main.cxx [changed mode: 0644->0755]
unit-tests/test-cases/strip-test3/Makefile.newtest [changed mode: 0644->0755]
unit-tests/test-cases/strip-test3/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/strip-test3/main.cxx [changed mode: 0644->0755]
unit-tests/test-cases/strip_local/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/strip_local/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/strip_local/hello.c [changed mode: 0644->0755]
unit-tests/test-cases/stripped-indirect-symbol-table/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/stripped-indirect-symbol-table/a.c [changed mode: 0644->0755]
unit-tests/test-cases/stripped-indirect-symbol-table/b.c [changed mode: 0644->0755]
unit-tests/test-cases/stripped-indirect-symbol-table/c.c [changed mode: 0644->0755]
unit-tests/test-cases/stripped-indirect-symbol-table/func.c [changed mode: 0644->0755]
unit-tests/test-cases/stripped-indirect-symbol-table/strip.list [changed mode: 0644->0755]
unit-tests/test-cases/stub-generation-weak/Makefile [new file with mode: 0755]
unit-tests/test-cases/stub-generation-weak/foo.c [new file with mode: 0755]
unit-tests/test-cases/stub-generation-weak/main.c [new file with mode: 0755]
unit-tests/test-cases/stub-generation/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/stub-generation/test.c [changed mode: 0644->0755]
unit-tests/test-cases/symbol-moving/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/symbol-moving/aaa.c [changed mode: 0644->0755]
unit-tests/test-cases/symbol-moving/anotb.c [changed mode: 0644->0755]
unit-tests/test-cases/symbol-moving/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/symbol-moving/bbb.c [changed mode: 0644->0755]
unit-tests/test-cases/symbol-moving/bnota.c [changed mode: 0644->0755]
unit-tests/test-cases/symbol-moving/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/symbol-moving/main.c [changed mode: 0644->0755]
unit-tests/test-cases/tentative-and-archive/Makefile [new file with mode: 0755]
unit-tests/test-cases/tentative-and-archive/foo.c [new file with mode: 0755]
unit-tests/test-cases/tentative-and-archive/main.c [new file with mode: 0755]
unit-tests/test-cases/tentative-and-dylib/Makefile [new file with mode: 0755]
unit-tests/test-cases/tentative-and-dylib/bar.c [new file with mode: 0755]
unit-tests/test-cases/tentative-and-dylib/foo.c [new file with mode: 0755]
unit-tests/test-cases/tentative-and-dylib/main.c [new file with mode: 0755]
unit-tests/test-cases/tentative-to-real-hidden/Makefile [new file with mode: 0755]
unit-tests/test-cases/tentative-to-real-hidden/test.c [new file with mode: 0755]
unit-tests/test-cases/tentative-to-real/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/tentative-to-real/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/tentative-to-real/test.c [changed mode: 0644->0755]
unit-tests/test-cases/thumb-blx/Makefile [new file with mode: 0755]
unit-tests/test-cases/thumb-blx/test.c [new file with mode: 0755]
unit-tests/test-cases/undefined-dynamic-lookup/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/undefined-dynamic-lookup/main.c [changed mode: 0644->0755]
unit-tests/test-cases/visibility-warning-dylib-v-archive/Makefile [new file with mode: 0755]
unit-tests/test-cases/visibility-warning-dylib-v-archive/bar.c [new file with mode: 0755]
unit-tests/test-cases/visibility-warning-dylib-v-archive/foo.c [new file with mode: 0755]
unit-tests/test-cases/visibility-warning-dylib-v-archive/main.c [new file with mode: 0755]
unit-tests/test-cases/visibility-warning/Makefile [new file with mode: 0755]
unit-tests/test-cases/visibility-warning/foo.c [new file with mode: 0755]
unit-tests/test-cases/visibility-warning/foo_hidden.c [new file with mode: 0755]
unit-tests/test-cases/visibility-warning/foo_weak.c [new file with mode: 0755]
unit-tests/test-cases/visibility-warning/foo_weak_hidden.c [new file with mode: 0755]
unit-tests/test-cases/weak-def-ordinal/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/weak-def-ordinal/bar.c [changed mode: 0644->0755]
unit-tests/test-cases/weak-def-ordinal/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/weak-def-ordinal/main.c [changed mode: 0644->0755]
unit-tests/test-cases/weak_dylib/Makefile [new file with mode: 0755]
unit-tests/test-cases/weak_dylib/bar.c [new file with mode: 0755]
unit-tests/test-cases/weak_dylib/bar.h [new file with mode: 0755]
unit-tests/test-cases/weak_dylib/foo.c [new file with mode: 0755]
unit-tests/test-cases/weak_dylib/foo.h [new file with mode: 0755]
unit-tests/test-cases/weak_dylib/main.c [new file with mode: 0755]
unit-tests/test-cases/weak_import/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/weak_import/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/weak_import/foo.h [changed mode: 0644->0755]
unit-tests/test-cases/weak_import/main.c [changed mode: 0644->0755]
unit-tests/test-cases/weak_import2/Makefile.newtest [changed mode: 0644->0755]
unit-tests/test-cases/weak_import2/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/weak_import2/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/weak_import2/foo.h [changed mode: 0644->0755]
unit-tests/test-cases/weak_import2/foo1.c [changed mode: 0644->0755]
unit-tests/test-cases/weak_import2/main.c [changed mode: 0644->0755]
unit-tests/test-cases/weak_import3/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/weak_import3/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/weak_import3/foo.c [changed mode: 0644->0755]
unit-tests/test-cases/weak_import3/foo.h [changed mode: 0644->0755]
unit-tests/test-cases/weak_import3/foo1.c [changed mode: 0644->0755]
unit-tests/test-cases/weak_import3/main.c [changed mode: 0644->0755]
unit-tests/test-cases/why_live/Makefile [new file with mode: 0755]
unit-tests/test-cases/why_live/bar.c [new file with mode: 0755]
unit-tests/test-cases/why_live/foo.c [new file with mode: 0755]
unit-tests/test-cases/why_live/main.c [new file with mode: 0755]
unit-tests/test-cases/zero-fill/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/zero-fill/test.c [changed mode: 0644->0755]
unit-tests/test-cases/zero-fill2/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/zero-fill2/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/zero-fill2/test.c [changed mode: 0644->0755]
unit-tests/test-cases/zero-fill3/Makefile [changed mode: 0644->0755]
unit-tests/test-cases/zero-fill3/comment.txt [changed mode: 0644->0755]
unit-tests/test-cases/zero-fill3/test.c [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index bcea8de..3f83489
--- a/ChangeLog
+++ b/ChangeLog
 
-2007-10-16     Nick Kledzik    <kledzik@apple.com>
+----- Tagged ld64-84.1.2
 
-       <rdar://problem/5556038> Cannot build with libm_static.a statically linked
-       * src/MachOWriterExecutable.hpp: fix when extern relocs are used with -r -d
-
------ Tagged ld64-77
-
-2007-07-3     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
+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
 
-2007-06-27     Nick Kledzik    <kledzik@apple.com>
+----- Tagged ld64-84.1
 
-       <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
+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
+       
 
-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
-
+----- Tagged ld64-84
 
-2007-06-26     Nick Kledzik    <kledzik@apple.com>
+2008-03-28     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
+       * src/LTOReader.hpp: don't print lto version, if lto is unavailable
        
 
-2007-06-26     Nick Kledzik    <kledzik@apple.com>
+2008-03-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
+       <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
        
 
-2007-06-26     Nick Kledzik    <kledzik@apple.com>
+2008-03-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
+       <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
        
 
------ Tagged ld64-75
-
-2007-05-31     Nick Kledzik    <kledzik@apple.com>
+2008-03-25     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
+       <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
 
 
------ Tagged ld64-74.5
+2008-03-25     Nick Kledzik    <kledzik@apple.com>
 
-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
+       <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
        
 
-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
+2008-03-25     Nick Kledzik    <kledzik@apple.com>
 
-2007-05-18     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
 
-       <rdar://problem/5211667> static probes don't work with libraries in dyld shared cache
-       *  src/OpaqueSection.hpp: the __TEXT segment is executable
 
+2008-03-24     Nick Kledzik    <kledzik@apple.com>
 
------ Tagged ld64-74.3
+       <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.
 
-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
-       
+2008-03-21     Nick Kledzik    <kledzik@apple.com>
 
-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()
+       * src/Options.cpp: warn if -seg1addr value is not page aligned
        
 
-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>
+2008-03-21     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
+       <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-74.1
-
-2007-05-09     Nick Kledzik    <kledzik@apple.com>
+----- Tagged ld64-83.2
        
-       * 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
+2008-03-15     Nick Kledzik    <kledzik@apple.com>
        
-
-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
+       <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
        
-
-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-83.1
 
------ Tagged ld64-74
+2008-03-14     Nick Kledzik    <kledzik@apple.com>
 
-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
+       <rdar://problem/5800466> -iphone_version_min ==> -iphoneos_version_min
+       * src/Options.cpp: support -iphoneos_version_min as well
        
 
-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
+----- Tagged ld64-83
 
+2008-03-10     Nick Kledzik    <kledzik@apple.com>
 
-2007-05-02     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
        
-       <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>
+2008-03-04     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
+       <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
        
 
-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
-
+----- Tagged ld64-82.7
 
-2007-04-30     Nick Kledzik    <kledzik@apple.com>
+2008-03-07     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
+       <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
 
-
-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
        
+----- Tagged ld64-82.6
 
-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
-
+2008-03-04     Nick Kledzik    <kledzik@apple.com>
 
-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
+       <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
        
-       
-2007-04-24     Nick Kledzik    <kledzik@apple.com>
+2008-03-04     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
+       <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
        
 
-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>
+2008-02-29     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
+       <rdar://problem/5774730> Simulator frameworks are being build split-seg and not prebound
+       * src/Options.cpp: only splitseg if prebound
 
 
-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
+2008-02-29     Nick Kledzik    <kledzik@apple.com>
 
-2007-05-10     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
 
-       <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
 
+2008-02-29     Nick Kledzik    <kledzik@apple.com>
 
-2007-05-09     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
 
-       <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
 
+2008-02-25     Nick Kledzik    <kledzik@apple.com>
 
------ Tagged ld64-73.6
+       <rdar://problem/5366363> ld -r -x 
+       * doc/man/man1/ld.1: update man page to explain -r -x produces auto-stripped labels
 
-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
+----- Tagged ld64-82.5
 
-2007-04-17     Nick Kledzik    <kledzik@apple.com>
+2008-02-12     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
+       <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
        
 
-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
-
+----- Tagged ld64-82.4
 
-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
+2008-02-06     Nick Kledzik    <kledzik@apple.com>
        
-
------ 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
+       <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
        
 
-2007-04-02     Nick Kledzik    <kledzik@apple.com>
+2008-02-06     Devang Patel    <dpatel@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
+       <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>
 
------ 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
+       * src/ld.cpp: fix for -arch ppc -mdynamic-no-pic -pie so PPC_RELOC_HA16 reloc is used
        
+----- Tagged ld64-82.3
        
------ Tagged ld64-73.1
-       
-2007-03-30     Nick Kledzik    <kledzik@apple.com>
+2008-02-04     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
+       <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$
        
 
-2007-03-30     Nick Kledzik    <kledzik@apple.com>
+----- Tagged ld64-82.2
 
-       * 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
+2008-01-30     Devang Patel    <dpatel@apple.com>
 
-2007-03-30     Nick Kledzik    <kledzik@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.
        
-       <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>
+----- Tagged ld64-82.1
 
-       <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
-       
+2008-01-23     Nick Kledzik    <kledzik@apple.com>
 
-2007-03-24     Nick Kledzik    <kledzik@apple.com>
+       * src/MachOReaderRelocatable.hpp: don't bus error if S_LITERAL_POINTERS is missing relocs
        
-       * src/MachOWriterExecutable.hpp: restructure writeAtoms() to copy all atoms in memory if possible
-
 
-2007-03-24     Nick Kledzik    <kledzik@apple.com>
+2008-01-22     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
+       <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
 
-
-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
+----- Tagged ld64-82
        
+2008-01-18     Nick Kledzik    <kledzik@apple.com>
 
-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
+       <rdar://problem/5694612> Bad grammar used in ld warning: cannot exported hidden symbol
+       * src/ld.cpp: fix typo in warning string
        
 
-2007-03-14     Nick Kledzik    <kledzik@apple.com>
+2008-01-16     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
-       
+       <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
+               
        
------ Tagged ld64-72
-
-2007-03-06     Nick Kledzik    <kledzik@apple.com>
-
-       * src/Options.cpp: ignore .objc_category_name_* symbols in .exp files
+2008-01-16     Nick Kledzik    <kledzik@apple.com>
        
-
-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 
+       <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
        
 
-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
+2008-01-16     Nick Kledzik    <kledzik@apple.com>
 
-
-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 
+       <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.
        
 
-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
-
+2008-01-16     Devang Patel    <dpatel@apple.com>
 
-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
+       * src/LLVMReader.hpp: Use __gnu_cxx::hash_map instead of hash supported by LLVM.
 
 
-2007-03-01     Nick Kledzik    <kledzik@apple.com>
+2008-01-16     Nick Kledzik    <kledzik@apple.com>
 
-       * doc/man/man1/ld.1: Add descriptions to all "rarely used options"
+       <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
 
 
-2007-03-01     Nick Kledzik    <kledzik@apple.com>
+2008-01-15     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
+       <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
 
-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
-               
+2008-01-14     Devang Patel    <dpatel@apple.com>
 
-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.
+       <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.
        
 
-2007-02-23     Nick Kledzik    <kledzik@apple.com>
+2008-01-14     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
+       <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
        
 
-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
-
+2008-01-11     Nick Kledzik    <kledzik@apple.com>
 
-2007-02-06     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
        
-       <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>
+2008-01-11     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
-       
+       * doc/man/man1/ld.1: add doc for -no_implicit_dylibs, -read_only_stubs, -slow_stubs, -interposable_list
        
-2007-01-28      Nick Kledzik    <kledzik@apple.com>
-
-       src/*: remove ObjectFile::requiresFollowOnAtom() method
        
+2008-01-11     Nick Kledzik    <kledzik@apple.com>
 
-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
+       <rdar://problem/4800212> ld64(1) man page uses ambiguous term "suffix"
+       * doc/man/man1/ld.1: make meaning of "suffix" more explicit
        
 
-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.
+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
+        
 
-2007-01-24      Nick Kledzik    <kledzik@apple.com>
+2008-01-11     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
+       <rdar://problem/5669751> Unknown error with linker (dyld: unknown external relocation type)
+       * src/ld.cpp: fix crash when SO stabs are not balanced
        
 
-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.
+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.
 
-2007-01-15      Nick Kledzik    <kledzik@apple.com>
+2000-01-10     Nick Kledzik    <kledzik@apple.com>
 
-       * src/MachOFileAbstraction.hpp: add range checking on macho_scattered_relocation_info::set_r_address()
+       <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
 
 
-2007-01-14      Nick Kledzik    <kledzik@apple.com>
+2008-01-03     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
+       <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-01-10      Nick Kledzik    <kledzik@apple.com>
+2007-12-19     Devang Patel    <dpatel@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
+       * src/LLVMReader.hpp: Add LLVM_LTO_VERSION #ifdef check.
        
+2007-12-19     Devang Patel    <dpatel@apple.com>
 
------ 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() 
-
+       * src/LLVMReader.hpp: Add fOptimizer NULL check before calling printVersion().
        
------ Tagged ld64-69.5
-
-2007-01-22      Nick Kledzik    <kledzik@apple.com>
+2007-12-19     Devang Patel    <dpatel@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
+       <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.
 
-       
------ 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
+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-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-81.4
 
------ Tagged ld64-69
+2007-12-18     Devang Patel    <dpatel@apple.com>
 
-2006-12-13      Nick Kledzik    <kledzik@apple.com>
+       * src/LLVMReader.hpp: Invalidate input architecture when optimizer is not available.
 
-       <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
+----- Tagged ld64-81.3
 
+2007-12-17     Nick Kledzik    <kledzik@apple.com>
 
-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
+       * ld64.xcodeproj/project.pbxproj: remove extraneous header search paths
+       
 
+2007-12-17     Devang Patel    <dpatel@apple.com>
 
-2006-11-28      Nick Kledzik    <kledzik@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.
 
-       <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>
+2007-12-14     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
+       <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
 
 
------ Tagged ld64-67
+2007-12-14     Devang Patel    <dpatel@apple.com>
 
-2006-11-17      Nick Kledzik    <kledzik@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>
 
-       * 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>
+       <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 
 
-       * Created new Subversion repository for ld64 from cvs tag ld64-27.2
old mode 100644 (file)
new mode 100755 (executable)
index f5c4f15..a8b0188
@@ -70,6 +70,8 @@ Both dynamic and static libraries are searched as they appear on the command lin
 maintains a list of directories to search for a library or framework to use.  The default
 library search path is /usr/lib then /usr/local/lib.  The -L option will add a new library search
 path.  The default framework search path is /Library/Frameworks then /System/Library/Frameworks.
+(Note: previously, /Network/Library/Frameworks was at the end of the default path.  If you need
+that functionality, you need to explicitly add -F/Network/Library/Frameworks). 
 The -F option will a new framework search path.  The -Z option will remove
 the standard search paths.  The -syslibroot option will prepend a prefix to all search
 paths.
@@ -139,6 +141,14 @@ clients linking to the library being created.  This was previously done with a s
 This is the same as listing a file name path to a library on the link line and it specifies that the 
 all symbols in library path should be available to clients linking to the library being created.
 This was previously done with a separate -sub_library option.
+.It Fl lazy-l Ns Ar x
+This is the same as the -lx but it is only for shared libraries and the linker
+will construct glue code so that the shared library is not loaded until 
+the first function in it is called.
+.It Fl lazy_library Ar path_to_library
+This is the same as listing a file name path to a shared library on the link line
+except that the linker will construct glue code so that the shared library is not 
+loaded until the first function in it is called.
 .It Fl L Ns dir
 Add 
 .Ar dir 
@@ -159,7 +169,7 @@ next path in the library search path is searched.
 .It Fl framework Ar name[,suffix]
 This option tells the linker to search for `name.framework/name' the framework search path.
 If the optional suffix is specified the framework is first searched for the name with the suffix and then without
-(e.g. look for `name.framework/name_suffix' first).
+(e.g. look for `name.framework/name_suffix' first, if not there try `name.framework/name').
 .It Fl weak_framework Ar name[,suffix]
 This is the same as the -framework name[,suffix] but forces the framework and all 
 references to it to be marked as weak imports. 
@@ -167,6 +177,11 @@ references to it to be marked as weak imports.
 This is the same as the -framework name[,suffix] but also specifies that the 
 all symbols in that framework should be available to clients linking to the library being created.
 This was previously done with a separate -sub_umbrella option.
+.It Fl lazy_framework Ar name[,suffix]
+This is the same as the -framework name[,suffix] except that the linker will 
+construct glue code so that the framework is not 
+loaded until the first function in it is called.  You cannot directly access
+data or Objective-C classes in a frameworked linked this way.
 .It Fl F Ns dir
 Add 
 .Ar dir
@@ -237,6 +252,14 @@ dylibs and bundles that a program loads, launch time can be improved because dyl
 It is often easier to not use this option, but instead use the rebase(1) tool, and give it a list of dylibs.  
 It will then choose non-overlapping addresses for the list and rebase them all.
 This option is also called -seg1addr for compatibility.
+.It Fl no_implicit_dylibs
+When creating a two-level namespace final linked image, normally the linker will hoist up public dylibs 
+that are implicitly linked to make the two-level namespace
+encoding more efficient for dyld.  For example, Cocoa re-exports AppKit and AppKit re-exports Foundation. 
+If you link with -framework Cocoa and use a symbol from Foundation, the linker will implicitly add a load
+command to load Foundation and encode the symbol as coming from Foundation.  If you use this option, 
+the linker will not add a load command for Foundation and encode the symbol as coming from Cocoa.  Then
+at runtime dyld will have to search Cocoa and AppKit before finding the symbol in Foundation.
 .El
 .Ss Options when creating a dynamic library (dylib)
 .Bl -tag
@@ -383,6 +406,13 @@ Add
 .Ar path
 to the runpath search path list for image being created.  At runtime, dyld uses the runpath when searching
 for dylibs whose load path begins with @rpath/.
+.It Fl commons Ar treatment
+Specifies how commons (aka tentative definitions) are resolved with respect to dylibs.  Options are: 
+ignore_dylibs, use_dylibs, error.  The default is ignore_dylibs which means the linker will turn a tentative
+definition in an object file into a real definition and not even check dylibs for conflicts.  The dylibs
+option means the linker should check linked dylibs for definitions and use them to replace tentative definitions 
+from object files.  The error option means the linker should issu an error whenever a tentative definition in an
+object file conflicts with an external symbol in a linked dylib.  See also -warn_commons.
 .El
 .Ss Options for introspecting the linker
 .Bl -tag
@@ -411,7 +441,11 @@ Writes a map file to the specified path which details all symbols and their addr
 Do not put debug information (STABS or DWARF) in the output file.
 .It Fl x
 Do not put non-global symbols in the output file's symbol table. Non-global symbols are useful when debugging and
-getting symbol names in back traces, but are not used at runtime.
+getting symbol names in back traces, but are not used at runtime. If -x is used with -r
+non-global symbol names are not removed, but instead replaced with a unique, duumy name
+that will be automatically removed when linked into a final linked image.  This
+allows dead code stripping, which uses symbols to break up code and data, to
+work properly and provides the security of having source symbol names removed.
 .It Fl non_global_symbols_strip_list Ar filename
 The specified 
 .Ar filename 
@@ -527,6 +561,25 @@ Add section based relocation records to a final linked image.  These relocations
 .It Fl warn_stabs
 Print a warning when the linker cannot do a BINCL/EINCL optimzation because the compiler put a bad stab symbol inside
 a BINCL/EINCL range.
+.It Fl warn_commons
+Print a warning whenever the a tentative definition in an object file is found and a external symbol by the same name
+is also found in a linked dylib.  This often means that the extern keyword is missing from a variable declaration
+in a header file.
+.It Fl read_only_stubs
+[i386 only] Makes the __IMPORT segment of a final linked images read-only.  This option makes a program slightly more
+secure in that the JMP instructions in the i386 fast stubs cannot be easily overwritten by malicious code.  The downside
+is the dyld must use mprotect() to temporily make the segment writable while it is binding the stubs. 
+.It Fl slow_stubs
+[i386 only]  Instead of using single JMP instruction stubs, the linker creates code in the __TEXT segment which 
+calls through a lazy pointer in the __DATA segment.  
+.It Fl interposable_list Ar filename
+The specified 
+.Ar filename 
+contains a list of global symbol names that should always be accessed indirectly.  For instance, if libSystem.dylib
+is linked such that _malloc is interposable, then calls to malloc() from within libSystem will go through a dyld
+stub and could potentially indirected to an alternate malloc.  If libSystem.dylib were built without making _malloc 
+interposable then if _malloc was interposed at runtime, calls to malloc from with libSystem would be missed 
+(not interposed) because they would be direct calls.
 .El
 .Ss Obsolete Options
 .Bl -tag
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index e8a771c..c13038e
@@ -52,7 +52,7 @@
 /* Begin PBXBuildRule section */
                F9E8D4BD07FCAF2000FD5801 /* PBXBuildRule */ = {
                        isa = PBXBuildRule;
-                       compilerSpec = com.apple.compilers.gcc.4_0;
+                       compilerSpec = com.apple.compilers.gcc;
                        fileType = sourcecode.c;
                        isEditable = 1;
                        outputFiles = (
@@ -60,7 +60,7 @@
                };
                F9E8D4BE07FCAF2A00FD5801 /* PBXBuildRule */ = {
                        isa = PBXBuildRule;
-                       compilerSpec = com.apple.compilers.gcc.4_0;
+                       compilerSpec = com.apple.compilers.gcc;
                        fileType = sourcecode.cpp;
                        isEditable = 1;
                        outputFiles = (
 /* End PBXCopyFilesBuildPhase section */
 
 /* Begin PBXFileReference section */
-               3DA587190ACC53BE0015C432 /* LLVMReader.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = LLVMReader.hpp; path = src/LLVMReader.hpp; sourceTree = "<group>"; };
+               3DA587190ACC53BE0015C432 /* LTOReader.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = LTOReader.hpp; path = src/LTOReader.hpp; sourceTree = "<group>"; };
                C02A29DE0953B26E001FB8C1 /* ChangeLog */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = ChangeLog; sourceTree = "<group>"; };
                F9023C3906D5A23E001BBF46 /* ld */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ld; sourceTree = BUILT_PRODUCTS_DIR; };
                F9023C3E06D5A254001BBF46 /* ExecutableFile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ExecutableFile.h; path = src/ExecutableFile.h; sourceTree = "<group>"; };
                F933D9460929277C0083EAC8 /* FileAbstraction.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = FileAbstraction.hpp; path = src/FileAbstraction.hpp; sourceTree = "<group>"; };
                F933D9470929277C0083EAC8 /* MachOFileAbstraction.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = MachOFileAbstraction.hpp; path = src/MachOFileAbstraction.hpp; sourceTree = "<group>"; };
                F933DC37092A82480083EAC8 /* Architectures.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = Architectures.hpp; path = src/Architectures.hpp; sourceTree = "<group>"; };
-               F933E3CB092E84250083EAC8 /* MachOReaderArchive.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = MachOReaderArchive.hpp; path = src/MachOReaderArchive.hpp; sourceTree = "<group>"; };
                F933E3CC092E84250083EAC8 /* MachOReaderDylib.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = MachOReaderDylib.hpp; path = src/MachOReaderDylib.hpp; sourceTree = "<group>"; };
                F933E3CD092E84250083EAC8 /* MachOReaderRelocatable.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = MachOReaderRelocatable.hpp; path = src/MachOReaderRelocatable.hpp; sourceTree = "<group>"; };
                F933E3CE092E84250083EAC8 /* MachOWriterExecutable.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = MachOWriterExecutable.hpp; path = src/MachOWriterExecutable.hpp; sourceTree = "<group>"; };
                F971EED706D5AD240041D381 /* ObjectDump.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ObjectDump.cpp; path = src/ObjectDump.cpp; sourceTree = "<group>"; };
                F97F5028070D0BB200B9FCD7 /* ld.1 */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.man; name = ld.1; path = doc/man/man1/ld.1; sourceTree = "<group>"; };
                F98D26850AA779BD00416316 /* OpaqueSection.hpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.h; name = OpaqueSection.hpp; path = src/OpaqueSection.hpp; sourceTree = "<group>"; };
+               F99F63CE0D99A291007F5394 /* ArchiveReader.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ArchiveReader.hpp; path = src/ArchiveReader.hpp; sourceTree = SOURCE_ROOT; };
                F9B1A2580A3A448800DA8FAB /* rebase.1 */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.man; name = rebase.1; path = doc/man/man1/rebase.1; sourceTree = "<group>"; };
                F9C0D48A06DD1E1B001C7193 /* Options.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = Options.cpp; path = src/Options.cpp; sourceTree = "<group>"; };
                F9C0D48B06DD1E1B001C7193 /* Options.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Options.h; path = src/Options.h; sourceTree = "<group>"; };
                                C02A29DE0953B26E001FB8C1 /* ChangeLog */,
                                F933DC37092A82480083EAC8 /* Architectures.hpp */,
                                F933D9460929277C0083EAC8 /* FileAbstraction.hpp */,
+                               F99F63CE0D99A291007F5394 /* ArchiveReader.hpp */,
                                F933D9470929277C0083EAC8 /* MachOFileAbstraction.hpp */,
                                F933E3CD092E84250083EAC8 /* MachOReaderRelocatable.hpp */,
-                               F933E3CB092E84250083EAC8 /* MachOReaderArchive.hpp */,
                                F933E3CC092E84250083EAC8 /* MachOReaderDylib.hpp */,
                                F933E3CE092E84250083EAC8 /* MachOWriterExecutable.hpp */,
-                               3DA587190ACC53BE0015C432 /* LLVMReader.hpp */,
+                               3DA587190ACC53BE0015C432 /* LTOReader.hpp */,
                                F9023C3E06D5A254001BBF46 /* ExecutableFile.h */,
                                F9023C4106D5A254001BBF46 /* ObjectFile.h */,
                                F98D26850AA779BD00416316 /* OpaqueSection.hpp */,
                                F9023C3F06D5A254001BBF46 /* ld.cpp */,
                                F9C0D48A06DD1E1B001C7193 /* Options.cpp */,
                                F9C0D48B06DD1E1B001C7193 /* Options.h */,
-                               F9EA7582097882F3008B4F1D /* debugline.c */,
                                F9EA7583097882F3008B4F1D /* debugline.h */,
+                               F9EA7582097882F3008B4F1D /* debugline.c */,
                                F9EA72D4097454FF008B4F1D /* machochecker.cpp */,
                                F971EED706D5AD240041D381 /* ObjectDump.cpp */,
                                F9EC78050A2F8674002A3E39 /* rebase.cpp */,
                        isa = PBXNativeTarget;
                        buildConfigurationList = F933D91B09291AC90083EAC8 /* Build configuration list for PBXNativeTarget "ld" */;
                        buildPhases = (
+                               0B12F6A50CE39466008ABCAE /* build configure.h */,
                                F9023C3606D5A23E001BBF46 /* Sources */,
                                F9023C3706D5A23E001BBF46 /* Frameworks */,
                                F97F5025070D0B6300B9FCD7 /* CopyFiles */,
-                               F9FCC3EF0A54A4ED00CEB866 /* ShellScript */,
+                               F9FCC3EF0A54A4ED00CEB866 /* Run Script */,
                        );
                        buildRules = (
                                F9E8D4BE07FCAF2A00FD5801 /* PBXBuildRule */,
                        productRefGroup = F9023C3A06D5A23E001BBF46 /* Products */;
                        projectDirPath = "";
                        projectRoot = "";
-                       shouldCheckCompatibility = 1;
                        targets = (
                                F9B1A2670A3A567B00DA8FAB /* all */,
                                F9023C3806D5A23E001BBF46 /* ld */,
 /* End PBXProject section */
 
 /* Begin PBXShellScriptBuildPhase section */
+               0B12F6A50CE39466008ABCAE /* build configure.h */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "build configure.h";
+                       outputPaths = (
+                               "$(DERIVED_FILE_DIR)/configure.h",
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+                       shellPath = /bin/bash;
+                       shellScript = "if [ -f /usr/local/include/llvm-c/lto.h ]; then\n\techo \"#define LTO_SUPPORT 1\" > ${DERIVED_FILE_DIR}/configure.h\nelse\n\techo \"#undef LTO_SUPPORT\t\" > ${DERIVED_FILE_DIR}/configure.h\nfi\n";
+                       showEnvVarsInLog = 0;
+               };
                F96D5367094A2754008E9EE8 /* ShellScript */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 2147483647;
                        shellScript = "# Let tests set MACOSX_DEPLOYMENT_TARGET as they need\nunsetenv MACOSX_DEPLOYMENT_TARGET\n\n# always use new linker\nsetenv LD_NO_CLASSIC_LINKER\nsetenv LD_NO_CLASSIC_LINKER_STATIC\n\n# run full test suite\n\"$SRCROOT\"/unit-tests/run-all-unit-tests\n\nexit 0";
                        showEnvVarsInLog = 0;
                };
-               F9FCC3EF0A54A4ED00CEB866 /* ShellScript */ = {
+               F9FCC3EF0A54A4ED00CEB866 /* Run Script */ = {
                        isa = PBXShellScriptBuildPhase;
                        buildActionMask = 8;
                        files = (
                        );
                        inputPaths = (
                        );
+                       name = "Run Script";
                        outputPaths = (
                        );
                        runOnlyForDeploymentPostprocessing = 1;
                        buildSettings = {
                                COPY_PHASE_STRIP = NO;
                                CURRENT_PROJECT_VERSION = "$(RC_ProjectSourceVersion)";
+                               DEAD_CODE_STRIPPING = NO;
                                DEBUG_INFORMATION_FORMAT = dwarf;
                                GCC_DYNAMIC_NO_PIC = YES;
                                GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
                                GCC_WARN_UNUSED_PARAMETER = NO;
                                GCC_WARN_UNUSED_VALUE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
+                               HEADER_SEARCH_PATHS = "$(DEVELOPER_DIR)/usr/include";
                                INSTALL_PATH = /usr/bin;
-                               MACOSX_DEPLOYMENT_TARGET = 10.5;
+                               MACOSX_DEPLOYMENT_TARGET = "";
                                OTHER_CPLUSPLUSFLAGS = "$(OTHER_CPLUSPLUSFLAGS)";
-                               OTHER_LDFLAGS = "";
                                PREBINDING = NO;
                                PRODUCT_NAME = ld;
                                SECTORDER_FLAGS = "";
                                GCC_MODEL_TUNING = G5;
                                GCC_OPTIMIZATION_LEVEL = 3;
                                GCC_PREPROCESSOR_DEFINITIONS = "$(GCC_PREPROCESSOR_DEFINITIONS_$(RC_RELEASE))";
-                               GCC_PREPROCESSOR_DEFINITIONS_CurryWeed = __OPEN_SOURCE__;
                                GCC_TREAT_WARNINGS_AS_ERRORS = NO;
                                GCC_WARN_ABOUT_INVALID_OFFSETOF_MACRO = NO;
                                GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
                                GCC_WARN_UNUSED_PARAMETER = NO;
                                GCC_WARN_UNUSED_VALUE = YES;
                                GCC_WARN_UNUSED_VARIABLE = YES;
+                               HEADER_SEARCH_PATHS = "$(DEVELOPER_DIR)/usr/include";
                                INSTALL_PATH = /usr/bin;
                                OTHER_CPLUSPLUSFLAGS = "$(OTHER_CPLUSPLUSFLAGS)";
-                               OTHER_LDFLAGS = "";
                                PREBINDING = NO;
                                PRODUCT_NAME = ld;
                                SECTORDER_FLAGS = "";
                                GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
                                GCC_MODEL_TUNING = G5;
                                GCC_OPTIMIZATION_LEVEL = 0;
+                               HEADER_SEARCH_PATHS = "$(DEVELOPER_DIR)/usr/include";
                                INSTALL_PATH = "$(HOME)/bin";
-                               OTHER_LDFLAGS = "";
+                               OTHER_LDFLAGS = "-Wl,-lazy_library,/Developer/usr/lib/libLTO.dylib";
                                OTHER_REZFLAGS = "";
                                PREBINDING = NO;
                                PRODUCT_NAME = ObjectDump;
                                GCC_MODEL_TUNING = G5;
                                GCC_OPTIMIZATION_LEVEL = s;
                                INSTALL_PATH = "$(HOME)/bin";
-                               OTHER_LDFLAGS = "";
+                               OTHER_LDFLAGS = "-Wl,-lazy_library,/Developer/usr/lib/libLTO.dylib";
                                OTHER_REZFLAGS = "";
                                PREBINDING = NO;
                                PRODUCT_NAME = ObjectDump;
                        buildSettings = {
                                GCC_DYNAMIC_NO_PIC = NO;
                                GCC_TREAT_WARNINGS_AS_ERRORS = NO;
+                               HEADER_SEARCH_PATHS = "$(DEVELOPER_DIR)/SDKs/Extra/usr/include";
                        };
                        name = Release;
                };
                                GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
                                GCC_MODEL_TUNING = G5;
                                GCC_PREPROCESSOR_DEFINITIONS = "$(GCC_PREPROCESSOR_DEFINITIONS_$(RC_RELEASE))";
-                               GCC_PREPROCESSOR_DEFINITIONS_CurryWeed = __OPEN_SOURCE__;
                                INSTALL_PATH = /usr/bin;
                                PREBINDING = NO;
                                PRODUCT_NAME = rebase;
old mode 100644 (file)
new mode 100755 (executable)
index 7089366..07f7fbb
@@ -1,6 +1,6 @@
 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
  *
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2005-2007 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -35,7 +35,7 @@ struct ppc
 {
        typedef Pointer32<BigEndian>            P;
        
-       enum ReferenceKinds {  kNoFixUp, kFollowOn, kPointer, kPointerWeakImport, kPointerDiff16, kPointerDiff32, kPointerDiff64,  
+       enum ReferenceKinds {  kNoFixUp, kFollowOn, kGroupSubordinate, kPointer, kPointerWeakImport, kPointerDiff16, kPointerDiff32, kPointerDiff64,  
                                                        kBranch24, kBranch24WeakImport, kBranch14,
                                                        kPICBaseLow16, kPICBaseLow14, kPICBaseHigh16, 
                                                        kAbsLow16, kAbsLow14, kAbsHigh16, kAbsHigh16AddLow, 
@@ -46,7 +46,7 @@ struct ppc64
 {
        typedef Pointer64<BigEndian>            P;
        
-       enum ReferenceKinds {  kNoFixUp, kFollowOn, kPointer, kPointerWeakImport, kPointerDiff16, kPointerDiff32, kPointerDiff64,
+       enum ReferenceKinds {  kNoFixUp, kFollowOn, kGroupSubordinate, kPointer, kPointerWeakImport, kPointerDiff16, kPointerDiff32, kPointerDiff64,
                                                        kBranch24, kBranch24WeakImport, kBranch14,
                                                        kPICBaseLow16, kPICBaseLow14, kPICBaseHigh16, 
                                                        kAbsLow16, kAbsLow14, kAbsHigh16, kAbsHigh16AddLow, 
@@ -57,8 +57,8 @@ struct x86
 {
        typedef Pointer32<LittleEndian>         P;
        
-       enum ReferenceKinds {  kNoFixUp, kFollowOn, kPointer, kPointerWeakImport, kPointerDiff, kPointerDiff16,
-                                                       kPCRel32, kPCRel32WeakImport, kAbsolute32,  kPCRel16, 
+       enum ReferenceKinds {  kNoFixUp, kFollowOn, kGroupSubordinate, kPointer, kPointerWeakImport, kPointerDiff, kPointerDiff16,
+                                                       kPCRel32, kPCRel32WeakImport, kAbsolute32,  kPCRel16, kPCRel8,
                                                        kDtraceProbe, kDtraceProbeSite, kDtraceIsEnabledSite, kDtraceTypeReference  };
 };
 
@@ -66,18 +66,22 @@ struct x86_64
 {
        typedef Pointer64<LittleEndian>         P;
        
-       enum ReferenceKinds {  kNoFixUp, kFollowOn, kPointer, kPointerWeakImport, kPointerDiff, kPointerDiff32, 
+       enum ReferenceKinds {  kNoFixUp, kFollowOn, kGroupSubordinate, kPointer, kPointerWeakImport, kPointerDiff, kPointerDiff32, 
                                                        kPCRel32, kPCRel32_1, kPCRel32_2, kPCRel32_4,
                                                        kBranchPCRel32, kBranchPCRel32WeakImport,
                                                        kPCRel32GOTLoad, kPCRel32GOTLoadWeakImport,
-                                                       kPCRel32GOT, kPCRel32GOTWeakImport,
+                                                       kPCRel32GOT, kPCRel32GOTWeakImport, kBranchPCRel8,
                                                        kDtraceProbe, kDtraceProbeSite, kDtraceIsEnabledSite, kDtraceTypeReference  };
 };
 
-
-
-
-
+struct arm
+{
+       typedef Pointer32<LittleEndian>         P;
+       
+       enum ReferenceKinds {  kNoFixUp, kFollowOn, kGroupSubordinate, kPointer, kPointerWeakImport, kPointerDiff,
+              kBranch24, kBranch24WeakImport, kThumbBranch22, kThumbBranch22WeakImport,
+                                                       kDtraceProbe, kDtraceProbeSite, kDtraceIsEnabledSite, kDtraceTypeReference  };
+};
 
 #endif // __ARCHITECTURES__
 
diff --git a/src/ArchiveReader.hpp b/src/ArchiveReader.hpp
new file mode 100755 (executable)
index 0000000..c3aebf8
--- /dev/null
@@ -0,0 +1,450 @@
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
+ *
+ * Copyright (c) 2005-2008 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@
+ */
+
+#ifndef __OBJECT_FILE_ARCHIVE__
+#define __OBJECT_FILE_ARCHIVE__
+
+#include <stdint.h>
+#include <math.h>
+#include <unistd.h>
+#include <sys/param.h>
+#include <mach-o/ranlib.h>
+#include <ar.h>
+
+#include <vector>
+#include <set>
+#include <algorithm>
+#include <ext/hash_map>
+
+#include "MachOFileAbstraction.hpp"
+#include "ObjectFile.h"
+#include "MachOReaderRelocatable.hpp"
+#if LTO_SUPPORT
+       #include "LTOReader.hpp"
+#endif
+namespace archive {
+
+typedef const struct ranlib* ConstRanLibPtr;
+
+template <typename A>
+class Reader : public ObjectFile::Reader
+{
+public:
+       static bool                                                                             validFile(const uint8_t* fileContent, uint64_t fileLength);
+                                                                                                       Reader(const uint8_t fileContent[], uint64_t fileLength,
+                                                                                                                       const char* path, time_t modTime, 
+                                                                                                                       const ObjectFile::ReaderOptions& options, uint32_t ordinalBase);
+       virtual                                                                                 ~Reader() {}
+
+       virtual const char*                                                             getPath()                       { return fPath; }
+       virtual time_t                                                                  getModificationTime(){ return fModTime; }
+       virtual DebugInfoKind                                                   getDebugInfoKind()      { return ObjectFile::Reader::kDebugInfoNone; }
+       virtual std::vector<class ObjectFile::Atom*>&   getAtoms();
+       virtual std::vector<class ObjectFile::Atom*>*   getJustInTimeAtomsFor(const char* name);
+       virtual std::vector<Stab>*                                              getStabs()                      { return NULL; }
+       virtual void                                                                    optimize(std::vector<ObjectFile::Atom*>&, std::vector<ObjectFile::Atom*>&, 
+                                                                                                                               std::vector<const char*>&,  uint32_t, ObjectFile::Reader* writer, 
+                                                                                                                               bool allGlobalsAReDeadStripRoots, int okind, 
+                                                                                                                               bool verbose, bool saveTemps, const char* outputFilePath,
+                                                                                                                               bool pie, bool allowTextRelocs);
+
+private:
+       static bool                                                                             validMachOFile(const uint8_t* fileContent, uint64_t fileLength);
+       static bool                                                                             validLTOFile(const uint8_t* fileContent, uint64_t fileLength);
+       static cpu_type_t                                                               architecture();
+
+
+       class Entry : ar_hdr
+       {
+       public:
+               const char*                     getName() const;
+               time_t                          getModTime() const;
+               const uint8_t*          getContent() const;
+               uint32_t                        getContentSize() const;
+               const Entry*            getNext() const;
+       private:
+               bool                            hasLongName() const;
+               unsigned int            getLongNameSpace() const;
+
+       };
+
+       class CStringEquals
+       {
+       public:
+               bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); }
+       };
+       typedef __gnu_cxx::hash_map<const char*, const struct ranlib*, __gnu_cxx::hash<const char*>, CStringEquals> NameToEntryMap;
+
+       typedef typename A::P                                                   P;
+       typedef typename A::P::E                                                E;
+
+       const struct ranlib*                                                    ranlibHashSearch(const char* name);
+       ObjectFile::Reader*                                                             makeObjectReaderForMember(const Entry* member);
+       void                                                                                    dumpTableOfContents();
+       void                                                                                    buildHashTable();
+
+       const char*                                                                             fPath;
+       time_t                                                                                  fModTime;
+       const ObjectFile::ReaderOptions&                                fOptions;
+       uint32_t                                                                                fOrdinalBase;
+       const uint8_t*                                                                  fFileContent;
+       uint64_t                                                                                fFileLength;
+       const struct ranlib*                                                    fTableOfContents;
+       uint32_t                                                                                fTableOfContentCount;
+       const char*                                                                             fStringPool;
+       std::vector<class ObjectFile::Atom*>                    fAllAtoms;
+       std::vector<class ObjectFile::Reader*>                  fInstantiatedReaders;
+       std::set<const class Entry*>                                    fInstantiatedEntries;
+       std::set<const class Entry*>                                    fPossibleEntries;
+       NameToEntryMap                                                                  fHashTable;
+
+       static std::vector<class ObjectFile::Atom*>             fgEmptyList;
+};
+
+template <typename A>
+std::vector<class ObjectFile::Atom*>           Reader<A>::fgEmptyList;
+
+
+template <typename A>
+bool Reader<A>::Entry::hasLongName() const
+{
+       return ( strncmp(this->ar_name, AR_EFMT1, strlen(AR_EFMT1)) == 0 );
+}
+
+template <typename A>
+unsigned int Reader<A>::Entry::getLongNameSpace() const
+{
+       char* endptr;
+       long result = strtol(&this->ar_name[strlen(AR_EFMT1)], &endptr, 10);
+       return result;
+}
+
+template <typename A>
+const char* Reader<A>::Entry::getName() const
+{
+       if ( this->hasLongName() ) {
+               int len = this->getLongNameSpace();
+               static char longName[256];
+               strncpy(longName, ((char*)this)+sizeof(ar_hdr), len);
+               longName[len] = '\0';
+               return longName;
+       }
+       else {
+               static char shortName[20];
+               strncpy(shortName, this->ar_name, 16);
+               shortName[16] = '\0';
+               char* space = strchr(shortName, ' ');
+               if ( space != NULL )
+                       *space = '\0';
+               return shortName;
+       }
+}
+
+template <typename A>
+time_t Reader<A>::Entry::getModTime() const
+{
+       char temp[14];
+       strncpy(temp, this->ar_date, 12);
+       temp[12] = '\0';
+       char* endptr;
+       return (time_t)strtol(temp, &endptr, 10);
+}
+
+
+template <typename A>
+const uint8_t* Reader<A>::Entry::getContent() const
+{
+       if ( this->hasLongName() )
+               return ((uint8_t*)this) + sizeof(ar_hdr) + this->getLongNameSpace();
+       else
+               return ((uint8_t*)this) + sizeof(ar_hdr);
+}
+
+
+template <typename A>
+uint32_t Reader<A>::Entry::getContentSize() const
+{
+       char temp[12];
+       strncpy(temp, this->ar_size, 10);
+       temp[10] = '\0';
+       char* endptr;
+       long size = strtol(temp, &endptr, 10);
+       // long name is included in ar_size
+       if ( this->hasLongName() )
+               size -= this->getLongNameSpace();
+       return size;
+}
+
+
+template <typename A>
+const class Reader<A>::Entry* Reader<A>::Entry::getNext() const
+{
+       const uint8_t* p = this->getContent() + getContentSize();
+       p = (const uint8_t*)(((uintptr_t)p+3) & (-4));  // 4-byte align
+       return (class Reader<A>::Entry*)p;
+}
+
+
+template <> cpu_type_t Reader<ppc>::architecture()    { return CPU_TYPE_POWERPC; }
+template <> cpu_type_t Reader<ppc64>::architecture()  { return CPU_TYPE_POWERPC64; }
+template <> cpu_type_t Reader<x86>::architecture()    { return CPU_TYPE_I386; }
+template <> cpu_type_t Reader<x86_64>::architecture() { return CPU_TYPE_X86_64; }
+template <> cpu_type_t Reader<arm>::architecture()    { return CPU_TYPE_ARM; }
+
+
+template <typename A>
+bool Reader<A>::validMachOFile(const uint8_t* fileContent, uint64_t fileLength)
+{
+       return mach_o::relocatable::Reader<A>::validFile(fileContent);
+}
+
+template <typename A>
+bool Reader<A>::validLTOFile(const uint8_t* fileContent, uint64_t fileLength)
+{
+#if LTO_SUPPORT
+       return lto::Reader::validFile(fileContent, fileLength, architecture());
+#else
+       return false;
+#endif
+}
+
+
+
+template <typename A>
+bool Reader<A>::validFile(const uint8_t* fileContent, uint64_t fileLength)
+{
+       // must have valid archive header
+       if ( strncmp((const char*)fileContent, "!<arch>\n", 8) != 0 )
+               return false;
+               
+       // peak at first .o file and verify it is correct architecture
+       const Entry* const start = (Entry*)&fileContent[8];
+       const Entry* const end = (Entry*)&fileContent[fileLength];
+       for (const Entry* p=start; p < end; p = p->getNext()) {
+               const char* memberName = p->getName();
+               // skip option table-of-content member
+               if ( (p==start) && ((strcmp(memberName, SYMDEF_SORTED) == 0) || (strcmp(memberName, SYMDEF) == 0)) )
+                       continue;
+               // archive is valid if first .o file is valid
+               return (validMachOFile(p->getContent(), p->getContentSize()) || validLTOFile(p->getContent(), p->getContentSize()));
+       }       
+       // empty archive
+       return true;
+}
+
+template <typename A>
+Reader<A>::Reader(const uint8_t fileContent[], uint64_t fileLength, const char* path, time_t modTime, 
+                                       const ObjectFile::ReaderOptions& options, uint32_t ordinalBase)
+ : fPath(NULL), fModTime(modTime), fOptions(options), fOrdinalBase(ordinalBase), fFileContent(NULL), 
+       fTableOfContents(NULL), fTableOfContentCount(0), fStringPool(NULL)
+{
+       fPath = strdup(path);
+       fFileContent = fileContent;
+       fFileLength = fileLength;
+
+       if ( strncmp((const char*)fileContent, "!<arch>\n", 8) != 0 )
+               throw "not an archive";
+
+       // write out path for -whatsloaded option
+       if ( options.fLogAllFiles )
+               printf("%s\n", path);
+
+       if ( !options.fFullyLoadArchives ) {
+               const Entry* const firstMember = (Entry*)&fFileContent[8];
+               if ( (strcmp(firstMember->getName(), SYMDEF_SORTED) == 0) || (strcmp(firstMember->getName(), SYMDEF) == 0) ) {
+                       const uint8_t* contents = firstMember->getContent();
+                       uint32_t ranlibArrayLen = E::get32(*((uint32_t*)contents));
+                       fTableOfContents = (const struct ranlib*)&contents[4];
+                       fTableOfContentCount = ranlibArrayLen / sizeof(struct ranlib);
+                       fStringPool = (const char*)&contents[ranlibArrayLen+8];
+                       if ( ((uint8_t*)(&fTableOfContents[fTableOfContentCount]) > &fileContent[fileLength])
+                               || ((uint8_t*)fStringPool > &fileContent[fileLength]) )
+                               throw "malformed archive, perhaps wrong architecture";
+                       this->buildHashTable();
+               }
+               else
+                       throw "archive has no table of contents";
+       }
+}
+
+
+template <typename A>
+ObjectFile::Reader* Reader<A>::makeObjectReaderForMember(const Entry* member)
+{
+       const char* memberName = member->getName();
+       char memberPath[strlen(fPath) + strlen(memberName)+4];
+       strcpy(memberPath, fPath);
+       strcat(memberPath, "(");
+       strcat(memberPath, memberName);
+       strcat(memberPath, ")");
+       //fprintf(stderr, "using %s from %s\n", memberName, fPath);
+       try {
+               // offset the ordinals in this mach-o .o file, so that atoms layout in same order as in archive
+               uint32_t ordinalBase =  fOrdinalBase + (uint8_t*)member - fFileContent;
+               if ( validMachOFile(member->getContent(), member->getContentSize()) ) {
+                       return new typename mach_o::relocatable::Reader<A>::Reader(member->getContent(), memberPath, member->getModTime(), fOptions, ordinalBase);
+               }
+#if LTO_SUPPORT
+               else if ( validLTOFile(member->getContent(), member->getContentSize()) ) {
+                       return new typename lto::Reader(member->getContent(), member->getContentSize(), memberPath, member->getModTime(), fOptions, architecture());
+               }
+#endif
+               throw "not a valid archive member";
+       }
+       catch (const char* msg) {
+               throwf("in %s, %s", memberPath, msg);
+       }
+}
+
+
+template <typename A>
+std::vector<class ObjectFile::Atom*>&  Reader<A>::getAtoms()
+{
+       if ( fOptions.fFullyLoadArchives ) {
+               // build vector of all atoms from all .o files in this archive
+               const Entry* const start = (Entry*)&fFileContent[8];
+               const Entry* const end = (Entry*)&fFileContent[fFileLength];
+               for (const Entry* p=start; p < end; p = p->getNext()) {
+                       const char* memberName = p->getName();
+                       if ( (p==start) && ((strcmp(memberName, SYMDEF_SORTED) == 0) || (strcmp(memberName, SYMDEF) == 0)) )
+                               continue;
+                       if ( fOptions.fWhyLoad )
+                               printf("-all_load forced load of %s(%s)\n", this->getPath(), memberName);
+                       ObjectFile::Reader* r = this->makeObjectReaderForMember(p);
+                       std::vector<class ObjectFile::Atom*>&   atoms = r->getAtoms();
+                       fAllAtoms.insert(fAllAtoms.end(), atoms.begin(), atoms.end());
+                       fInstantiatedReaders.push_back(r);
+               }
+               return fAllAtoms;
+       }
+       else if ( fOptions.fLoadAllObjcObjectsFromArchives ) {
+               // build vector of all atoms from all .o files containing objc classes in this archive
+               for(class NameToEntryMap::iterator it = fHashTable.begin(); it != fHashTable.end(); ++it) {
+                       if ( (strncmp(it->first, ".objc_c", 7) == 0) || (strncmp(it->first, "_OBJC_CLASS_$_", 14) == 0) ) {
+                               const Entry* member = (Entry*)&fFileContent[E::get32(it->second->ran_off)];
+                               if ( fInstantiatedEntries.count(member) == 0 ) {
+                                       if ( fOptions.fWhyLoad )
+                                               printf("-ObjC forced load of %s(%s)\n", this->getPath(), member->getName());
+                                       // only return these atoms once
+                                       fInstantiatedEntries.insert(member);
+                                       ObjectFile::Reader* r = makeObjectReaderForMember(member);
+                                       std::vector<class ObjectFile::Atom*>&   atoms = r->getAtoms();
+                                       fAllAtoms.insert(fAllAtoms.end(), atoms.begin(), atoms.end());
+                                       fInstantiatedReaders.push_back(r);
+                               }
+                       }
+               }
+               return fAllAtoms;
+       }
+       else {
+               // return nonthing for now, getJustInTimeAtomsFor() will return atoms as needed
+               return fgEmptyList;
+       }
+}
+
+template <typename A>
+void  Reader<A>::optimize(std::vector<ObjectFile::Atom*>& allAtoms, std::vector<ObjectFile::Atom*>& newAtoms, 
+                                                       std::vector<const char*>& additionalUndefines, uint32_t nextOrdinal, ObjectFile::Reader* writer, 
+                                                       bool allGlobalsAReDeadStripRoots, int okind, 
+                                                       bool verbose, bool saveTemps, const char* outputFilePath,
+                                                       bool pie, bool allowTextRelocs)
+{
+       for(std::vector<ObjectFile::Reader*>::iterator it=fInstantiatedReaders.begin(); it != fInstantiatedReaders.end(); ++it) {
+               (*it)->optimize(allAtoms, newAtoms, additionalUndefines, nextOrdinal, writer, allGlobalsAReDeadStripRoots, 
+                                                       okind, verbose, saveTemps, outputFilePath, pie, allowTextRelocs);
+       }
+}
+
+
+
+template <typename A>
+ConstRanLibPtr  Reader<A>::ranlibHashSearch(const char* name)
+{
+       class NameToEntryMap::iterator pos = fHashTable.find(name);
+       if ( pos != fHashTable.end() )
+               return pos->second;
+       else
+               return NULL;
+}
+
+template <typename A>
+void Reader<A>::buildHashTable()
+{
+       // walk through list backwards, adding/overwriting entries
+       // this assures that with duplicates those earliest in the list will be found
+       for (int i = fTableOfContentCount-1; i >= 0; --i) {
+               const struct ranlib* entry = &fTableOfContents[i];
+               const char* entryName = &fStringPool[E::get32(entry->ran_un.ran_strx)];
+               const Entry* member = (Entry*)&fFileContent[E::get32(entry->ran_off)];
+               //fprintf(stderr, "adding hash %d, %s -> %p\n", i, entryName, entry);
+               fHashTable[entryName] = entry;
+               fPossibleEntries.insert(member);
+       }
+}
+
+template <typename A>
+void Reader<A>::dumpTableOfContents()
+{
+       for (unsigned int i=0; i < fTableOfContentCount; ++i) {
+               const struct ranlib* e = &fTableOfContents[i];
+               printf("%s in %s\n", &fStringPool[E::get32(e->ran_un.ran_strx)], ((Entry*)&fFileContent[E::get32(e->ran_off)])->getName());
+       }
+}
+
+template <typename A>
+std::vector<class ObjectFile::Atom*>* Reader<A>::getJustInTimeAtomsFor(const char* name)
+{
+       if ( fOptions.fFullyLoadArchives ) {
+               return NULL;
+       }
+       else {
+               const struct ranlib* result = NULL;
+               // do a hash search of table of contents looking for requested symbol
+               result = ranlibHashSearch(name);
+               if ( result != NULL ) {
+                       const Entry* member = (Entry*)&fFileContent[E::get32(result->ran_off)];
+                       if ( fInstantiatedEntries.count(member) == 0 ) {
+                               if ( fOptions.fWhyLoad )
+                                       printf("%s forced load of %s(%s)\n", name, this->getPath(), member->getName());
+                               // only return these atoms once
+                               fInstantiatedEntries.insert(member);
+                               ObjectFile::Reader* r = makeObjectReaderForMember(member);
+                               fInstantiatedReaders.push_back(r);
+                               return new std::vector<class ObjectFile::Atom*>(r->getAtoms());
+                       }
+               }
+               //fprintf(stderr, "%s NOT found in archive %s\n", name, fPath);
+               return NULL;
+       }
+}
+
+
+
+
+
+}; // namespace archive
+
+
+#endif // __OBJECT_FILE_ARCHIVE__
old mode 100644 (file)
new mode 100755 (executable)
index 8fa7099..b0b760d
@@ -55,9 +55,11 @@ namespace ExecutableFile {
                                                                                                                          std::vector<class ObjectFile::Reader::Stab>& stabs,
                                                                                                                          class ObjectFile::Atom* entryPointAtom,
                                                                                                                          class ObjectFile::Atom* dyldHelperAtom,
+                                                                                                                         class ObjectFile::Atom* dyldLazyDylibHelperAtom,
                                                                                                                          bool createUUID, bool canScatter,
                                                                                                                          ObjectFile::Reader::CpuConstraint cpuConstraint,
-                                                                                                                         bool biggerThanTwoGigs) = 0;
+                                                                                                                         bool biggerThanTwoGigs,
+                                                                                                                         bool overridesDylibWeakDefines) = 0;
 
        protected:
                                                                        Writer(std::vector<DyLibUsed>&) {};
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/src/LLVMReader.hpp b/src/LLVMReader.hpp
deleted file mode 100644 (file)
index e49c5ae..0000000
+++ /dev/null
@@ -1,561 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
- *
- * Copyright (c) 2006-2007 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@
- */
-
-#ifndef __LLVM_READER_H__
-#define __LLVM_READER_H__
-
-#include <stdlib.h>
-#include <vector>
-#include "MachOFileAbstraction.hpp"
-#include "Architectures.hpp"
-#include "ObjectFile.h"
-#include "llvm/LinkTimeOptimizer.h"
-
-#define LLVMLinkTimeOptimizer "LLVMlto.dylib"
-
-class LLVMReader;
-
-//
-// LLVMReference handles LLVMAtom references. These references facilitate 
-// symbol resolution.
-//
-
-class LLVMReference : public ObjectFile::Reference
-{
-public:
-                                                                               LLVMReference (const char *n) : fName(n), fAtom(0), fFromAtom(0) { }
-
-       bool                                                            isTargetUnbound() const                         { return fAtom == 0; }
-       bool                                                            isFromTargetUnbound() const             { return true; }
-       uint8_t                                                         getKind() const                                         { return 0; }
-       uint64_t                                                        getFixUpOffset() const                          { return 0; }
-       const char *                                            getTargetName() const                           { return fName; }
-       ObjectFile::Atom&                                       getTarget() const                                       { return *fAtom; }
-       uint64_t                                                        getTargetOffset() const                         { return 0; }
-       bool                                                            hasFromTarget() const                           { return false; }
-       ObjectFile::Atom&                                       getFromTarget() const                           { return *fFromAtom; }
-       const char *                                            getFromTargetName() const                       { return NULL; }
-       uint64_t                                                        getFromTargetOffset() const             { return 0; }
-       TargetBinding                                           getTargetBinding() const;
-       TargetBinding                                           getFromTargetBinding() const  { return kDontBind; }
-       void                                                            setTarget (ObjectFile::Atom &a, uint64_t offset) 
-                                                                               { fAtom = &a; }
-       void                                                            setFromTarget(ObjectFile::Atom &a)      { }
-       const char *                                            getDescription() const                          { return NULL; }
-
-private:
-       const char *                                            fName;
-       ObjectFile::Atom *                                      fAtom;
-       ObjectFile::Atom *                                      fFromAtom;
-};
-
-ObjectFile::Reference::TargetBinding LLVMReference::getTargetBinding() const 
-{ 
-       if (strncmp (fName, "__ld64.llvm", 11) == 0)
-               return kDontBind;
-       else return kUnboundByName;
-}
-
-//
-// LLVMAtom acts as a proxy Atom for the symbols that are exported by LLVM bytecode file. Initially,
-// LLVMReader creates LLVMAtoms to allow linker proceed with usual symbol resolution phase. After
-// optimization is performed, real Atoms are created for these symobls. However these real Atoms
-// are not inserted into global symbol table. LLVMAtom holds real Atom and forwards appropriate
-// methods to real atom.
-//
-
-class LLVMAtom : public ObjectFile::Atom
-{
-public:
-       ObjectFile::Reader *                                            getFile() const                         { return fOwner; }
-       bool                                                                            getTranslationUnitSource (const char **dir, const char **name) const 
-                                                                                                                                                       { return fRealAtom->getTranslationUnitSource (dir, name); }
-       const char *                                                            getName () const                        { return fAtomName;     }
-       const char *                                                            getDisplayName() const          { return this->getName(); }
-       Scope                                                                           getScope() const                        { return fScope; }
-       DefinitionKind                                                          getDefinitionKind() const;
-       SymbolTableInclusion                                            getSymbolTableInclusion() const 
-                                                                                                                                                       { return fRealAtom->getSymbolTableInclusion(); }
-       bool                                                                            dontDeadStrip() const           { return false; }
-       bool                                                                            isZeroFill() const                      { return fRealAtom->isZeroFill(); }
-       uint64_t                                                                        getSize() const                         { return fRealAtom->getSize(); }
-       std::vector<ObjectFile::Reference*>&            getReferences() const 
-                                                                                                                                                       { return (fRealAtom ? fRealAtom->getReferences() : (std::vector<ObjectFile::Reference*>&)fReferences); }
-       bool                                                                            mustRemainInSection() const { return fRealAtom->mustRemainInSection(); }
-       const char *                                                            getSectionName() const          { return (fRealAtom ? fRealAtom->getSectionName() : NULL); }
-       // Linker::optimize() sets section for this atom, not fRealAtom. Use this Atom's fSection.
-       class ObjectFile::Section *                                     getSection() const                      { return fSection; }
-       ObjectFile::Segment&                                            getSegment() const                      { return fRealAtom->getSegment(); }
-       uint32_t                                                                        getOrdinal() const { return (fRealAtom ? fRealAtom->getOrdinal() : 0); }
-       ObjectFile::Atom&                                                       getFollowOnAtom() const         { return fRealAtom->getFollowOnAtom(); }
-       std::vector<ObjectFile::LineInfo>*                      getLineInfo() const             { return fRealAtom->getLineInfo(); }
-       ObjectFile::Alignment                                           getAlignment() const;
-       void                                                                            copyRawContent(uint8_t buffer[]) const 
-                                                                                                                                                       { fRealAtom->copyRawContent(buffer); }
-       void                                                                            setScope(Scope s)                       { if (fRealAtom) fRealAtom->setScope(s); }
-
-       LLVMAtom(ObjectFile::Reader *owner, const char *n, llvm::LLVMSymbol *ls);
-       
-       void                                                                            setRealAtom (ObjectFile::Atom *atom) 
-                                                                                                                                                       { fRealAtom = atom; }
-       void                                                                            addReference(ObjectFile::Reference *ref) 
-                                                                                                                                                       { fReferences.push_back(ref); }
-
-       void                                                                            setSectionOffset(uint64_t offset) { fSectionOffset = offset; if (fRealAtom) fRealAtom->setSectionOffset(offset); }
-       void                                                                            setSection(class ObjectFile::Section* sect) { fSection = sect; if (fRealAtom) fRealAtom->setSection(sect); }
-                                                                                                                                                       
-private:
-       ObjectFile::Reader *                                            fOwner;
-       const char *                                                            fAtomName;
-       llvm::LLVMSymbol *                                                      fLLVMSymbol;
-       ObjectFile::Atom *                                                      fRealAtom;
-       std::vector<ObjectFile::Reference*>             fReferences;
-       ObjectFile::Atom::Scope                                         fScope;
-       ObjectFile::Atom::DefinitionKind                        fDefKind;
-};
-
-ObjectFile::Atom::DefinitionKind LLVMAtom::getDefinitionKind() const 
-{ 
-       if (fRealAtom) 
-               return fRealAtom->getDefinitionKind();
-       else
-               return fDefKind;
-}
-
-LLVMAtom::LLVMAtom(ObjectFile::Reader *owner, const char *n, llvm::LLVMSymbol *ls) : fOwner(owner), fAtomName(n), fLLVMSymbol(ls), fRealAtom(0) 
-{
-
-       if (!ls) return;
-
-       switch (ls->getLinkage()) {
-       case llvm::LTOExternalLinkage:
-               fScope = scopeGlobal;
-               fDefKind = kRegularDefinition;
-               break;
-       case llvm::LTOLinkOnceLinkage:
-       case llvm::LTOWeakLinkage:
-               // ??? How to differentiate between this two linkage types ?
-               fScope = scopeGlobal;
-               fDefKind = kWeakDefinition;
-               break;
-       default:
-               throw "Unexpected LLVM Symbol Linkage info\n";
-               break;
-       }
-}
-
-ObjectFile::Alignment LLVMAtom::getAlignment() const
-{
-       if (fRealAtom)
-               return fRealAtom->getAlignment(); 
-       else {
-               ObjectFile::Alignment alignment(fLLVMSymbol->getAlignment());
-               return alignment;
-       }
-}
-
-//
-// LLVMReader does not expose internal symbols defined and used inside bytecode file. However, 
-// these symbols may refere other external symbols. IntercessorAtom facilitate by acting as a 
-// orignator of such references during pre-optimization symbol resoultion phase. These atoms
-// are immediately removed after optimization.
-//
-
-class IntercessorAtom : public ObjectFile::Atom
-{
-public:
-       ObjectFile::Reader *                                            getFile() const                         { return fOwner; }
-       bool                                                                            getTranslationUnitSource (const char **dir, const char **name) const 
-                                                                                                                                                       { return false; }
-       const char *                                                            getName () const                        { return fAtomName;     }
-       const char *                                                            getDisplayName() const          { return this->getName(); }
-       Scope                                                                           getScope() const                        { return scopeGlobal; }
-       DefinitionKind                                                          getDefinitionKind() const   { return kRegularDefinition; }
-       SymbolTableInclusion                                            getSymbolTableInclusion() const 
-       { return kSymbolTableNotIn; }
-       bool                                                                            dontDeadStrip() const           { return false; }
-       bool                                                                            isZeroFill() const                      { return false; }
-       uint64_t                                                                        getSize() const                         { return 0; }
-       std::vector<ObjectFile::Reference*>&            getReferences() const           { return  (std::vector<ObjectFile::Reference*>&)fReferences; }
-       bool                                                                            mustRemainInSection() const { return false; }
-       const char *                                                            getSectionName() const          { return NULL; }
-       class ObjectFile::Section *                                     getSection() const                      { return NULL; }
-       ObjectFile::Segment&                                            getSegment() const                      { return this->getSegment(); }
-       uint32_t                                                                        getOrdinal() const          { return 0; }
-       ObjectFile::Atom&                                                       getFollowOnAtom() const         { return this->getFollowOnAtom(); }
-       std::vector<ObjectFile::LineInfo>*                      getLineInfo() const             { return NULL; }
-       ObjectFile::Alignment                                           getAlignment() const            { ObjectFile::Alignment a(0); return a; }
-       void                                                                            copyRawContent(uint8_t buffer[]) const 
-                                                                                                                                                       { }
-       void                                                                            setScope(Scope s)                       { }
-
-
-       IntercessorAtom(ObjectFile::Reader *owner, std::set<std::string> &references);
-       
-       void                                                                            addReference(ObjectFile::Reference *ref) 
-                                                                                                                                                       { fReferences.push_back(ref); }
-       void                                                                            addReferences(std::set<std::string> &references);
-private:
-       ObjectFile::Reader *                                            fOwner;
-       char *                                                          fAtomName;
-       std::vector<ObjectFile::Reference*>             fReferences;
-       ObjectFile::Atom::Scope                                         fScope;
-       ObjectFile::Atom::DefinitionKind                        fDefKind;
-};
-
-IntercessorAtom::IntercessorAtom(ObjectFile::Reader *owner, std::set<std::string> &references)
-{
-       static int sCount = 0;
-       fOwner = owner;
-       fAtomName = (char *) malloc (sizeof(char)*20);
-       sprintf (fAtomName,"__ld64.llvm%d__",sCount++);
-
-       for (std::set<std::string>::iterator it = references.begin(); it != references.end(); it++) {
-       std::string r = *it;
-       this->addReference(new LLVMReference(r.c_str()));
-       }
-}
-
-void IntercessorAtom::addReferences(std::set<std::string> &references)
-{
-       for (std::set<std::string>::iterator it = references.begin(); it != references.end(); it++) {
-       std::string r = *it;
-       this->addReference(new LLVMReference(r.c_str()));
-       }
-}
-
-class InIntercessorSet
-{
-public:
-       InIntercessorSet(std::set<ObjectFile::Atom*>& iAtoms) : fIntercessorAtoms(iAtoms) {}
-
-       bool operator()(ObjectFile::Atom*& atom) const {
-               return ( fIntercessorAtoms.count(atom) != 0 );
-       }
-
-private:
-       std::set<ObjectFile::Atom*>& fIntercessorAtoms;
-};
-
-//
-// LLVMOptimizer class is responsible for communicating with LLVM LTO library.
-// One LLVMOptimizer object is created per Linker invocation. All LLVMReaders share this
-// one single optimizer object.
-//
-
-class LLVMOptimizer
-{
-public:
-                                                                                               LLVMOptimizer(Options &opt);
-                                                                                               ~LLVMOptimizer()                                { if (fLLVMHandle) dlclose(fLLVMHandle);        }
-
-
-       void                                                                            optimize(std::vector<ObjectFile::Atom *>&, std::vector<ObjectFile::Atom*>&, uint32_t);
-       void                                                                            read(ObjectFile::Reader *, const char *, std::set<std::string>&, std::vector<ObjectFile::Atom*>&, const char *);
-       void                                                                            reconcileOptimizedAtoms(std::vector<class ObjectFile::Atom*>&, std::vector<class ObjectFile::Atom*>&);
-       void                                                                            addIntercessor(IntercessorAtom * atom) { fIntercessorAtoms.insert(atom); }
-       void                                                                            addReader(ObjectFile::Reader *reader) { fLLVMReaders[reader->getPath()] = reader; }
-       cpu_type_t                                                                      getCpuType(std::string &targetTriple);
-       bool                                                                            validArchitecture(const char *path, cpu_type_t architecture);
-       class LCStringEquals
-       {
-       public:
-               bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); }
-       };
-       typedef hash_map<const char*, LLVMAtom*, hash<const char*>, LCStringEquals> LLVMAtomToNameMapper;
-       typedef hash_map<const char*, ObjectFile::Reader*, hash<const char*>, LCStringEquals> ReaderToPathMapper;
-       
-    typedef llvm::LinkTimeOptimizer * (*createLLVMOptimizer_func_t) ();
-private:
-       bool                                                                            fOptimized;
-       llvm::LinkTimeOptimizer                                         *fOptimizer;
-       void                                                                            *fLLVMHandle;
-       LLVMAtomToNameMapper                                            fLLVMSymbols;
-       Options&                                                                        fOptions;
-       std::set<ObjectFile::Atom*>                                     fIntercessorAtoms;
-       ReaderToPathMapper                                                      fLLVMReaders;
-};
-
-LLVMOptimizer::LLVMOptimizer(Options &opts) : fOptions(opts)
-{
-       fLLVMHandle = (llvm::LinkTimeOptimizer *) dlopen (LLVMLinkTimeOptimizer, RTLD_LAZY);
-       if (!fLLVMHandle)
-               throwf("Unable to load LLVM library: \n", dlerror());
-
-       createLLVMOptimizer_func_t createLLVMOptimizer_fp = (createLLVMOptimizer_func_t)dlsym(fLLVMHandle, "createLLVMOptimizer");
-       if (createLLVMOptimizer_fp == NULL)
-               throwf("couldn't find \"createLLVMOptimizer\" ", dlerror());
-       fOptimizer = createLLVMOptimizer_fp();
-       fOptimized = false;
-}
-
-cpu_type_t LLVMOptimizer::getCpuType(std::string &targetTriple)
-{
-       if ( strncmp (targetTriple.c_str(), "powerpc-", 8) == 0)
-               return CPU_TYPE_POWERPC;
-       else if ( strncmp (targetTriple.c_str(), "powerpc64-", 10))
-               return CPU_TYPE_POWERPC64;
-       // match "i[3-9]86-*".
-       else if ( targetTriple.size() >= 5 && targetTriple[0] == 'i' && targetTriple[2] == '8' && targetTriple[3] == '6' && targetTriple[4] == '-' && targetTriple[1] - '3' < 6  )
-               return CPU_TYPE_I386;
-       else
-               return CPU_TYPE_ANY;
-}
-
-bool LLVMOptimizer::validArchitecture(const char *path, cpu_type_t architecture)
-{
-       std::string targetTriple;
-       fOptimizer->getTargetTriple(path, targetTriple);
-       if (architecture != getCpuType(targetTriple)) {
-               fOptimizer->removeModule(path);
-               return false;
-       }
-
-       return true;
-}
-
-void LLVMOptimizer::optimize(std::vector<ObjectFile::Atom*> &allAtoms, std::vector<ObjectFile::Atom*> &newAtoms, uint32_t nextInputOrdinal)
-{
-       if (fOptimized)
-               return;
-
-       char * tmp = "/tmp/ld64XXXXXXXX";
-       char * bigOfile = (char *) malloc (strlen (tmp) + 3);
-       if (!bigOfile)
-               throw "Unable to create temp file name";
-       strcpy (bigOfile, tmp);
-       mktemp (bigOfile);
-       strcat (bigOfile, ".o");
-
-       std::vector <const char *> exportList;
-       for (std::vector<ObjectFile::Atom*>::iterator it = allAtoms.begin(); it != allAtoms.end(); ++it) {
-               ObjectFile::Atom *atom = *it;
-               if (atom->getName()) {
-                       ReaderToPathMapper::iterator pos = fLLVMReaders.find(atom->getFile()->getPath());
-                       if (pos != fLLVMReaders.end())
-                               exportList.push_back(atom->getName());
-               }
-                       
-       }
-
-       std::string targetTriple;
-       llvm::LTOStatus status = fOptimizer->optimizeModules(bigOfile, exportList, targetTriple, fOptions.saveTempFiles(), fOptions.getOutputFilePath());
-       if (status != llvm::LTO_OPT_SUCCESS) {
-               if (status == llvm::LTO_WRITE_FAILURE)
-                       throw "Unable to write optimized output file";
-               if (status == llvm::LTO_ASM_FAILURE)
-                       throw "Unable to assemble optimized output file";
-               if (status == llvm::LTO_MODULE_MERGE_FAILURE)
-                       throw "Unable to merge bytecode files";
-               if (status == llvm::LTO_NO_TARGET)
-                       throw "Unable to load target optimizer";
-       }
-       fOptimized = true;
-
-       Options::FileInfo info = fOptions.findFile (bigOfile);
-       ObjectFile::Reader* nr = NULL;
-       int fd = ::open(info.path, O_RDONLY, 0);
-       if ( fd == -1 )
-               throwf("can't open file, errno=%d", errno);
-       if ( info.fileLen < 20 )
-               throw "file too small";
-
-       uint8_t* p = (uint8_t*)::mmap(NULL, info.fileLen, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0);
-       if ( p == (uint8_t*)(-1) )
-               throwf("can't map file, errno=%d", errno);
-       
-       cpu_type_t cpt = getCpuType(targetTriple);
-       switch (cpt) {
-       case CPU_TYPE_POWERPC:
-               if ( mach_o::relocatable::Reader<ppc>::validFile(p) )
-                       nr = new mach_o::relocatable::Reader<ppc>(p, info.path, info.modTime, fOptions.readerOptions(), nextInputOrdinal);
-               break;
-       case CPU_TYPE_POWERPC64:
-               if ( mach_o::relocatable::Reader<ppc64>::validFile(p) )
-                       nr = new mach_o::relocatable::Reader<ppc64>(p, info.path, info.modTime, fOptions.readerOptions(), nextInputOrdinal);
-               break;
-       case CPU_TYPE_I386:
-               if ( mach_o::relocatable::Reader<x86>::validFile(p) )
-                       nr = new mach_o::relocatable::Reader<x86>(p, info.path, info.modTime, fOptions.readerOptions(), nextInputOrdinal);
-               break;
-       default:
-               throw "file is not of required architecture";
-               break;
-       }
-
-       std::vector<class ObjectFile::Atom*> optimizedAtoms;
-       optimizedAtoms = nr->getAtoms();
-       reconcileOptimizedAtoms(optimizedAtoms, newAtoms);
-
-       allAtoms.erase(std::remove_if(allAtoms.begin(), allAtoms.end(), InIntercessorSet(fIntercessorAtoms)), allAtoms.end());
-       unlink(bigOfile);
-       free(bigOfile); 
-}
-
-void LLVMOptimizer::read(ObjectFile::Reader *reader, const char *path, std::set<std::string> &references, std::vector<ObjectFile::Atom*> &atoms, const char *intercessorName)
-{
-       llvm::LinkTimeOptimizer::NameToSymbolMap symbols;
-       llvm::LTOStatus status = fOptimizer->readLLVMObjectFile (path, symbols, references);
-       if (status != llvm::LTO_READ_SUCCESS)
-               throw "Unable to read LLVM bytecode file";
-
-       for (llvm::LinkTimeOptimizer::NameToSymbolMap::iterator itr = symbols.begin();
-                itr != symbols.end(); itr++) {
-               const char *name = itr->first;
-               llvm::LLVMSymbol *ls = itr->second;
-               LLVMAtom *a = new LLVMAtom(reader, name, ls);
-
-               LLVMAtomToNameMapper::iterator pos = fLLVMSymbols.find(name);
-               bool insertNewAtom = true;
-               if (pos != fLLVMSymbols.end()) {
-                       LLVMAtom *existingAtom = pos->second;
-                       ObjectFile::Atom::DefinitionKind newDefKind = a->getDefinitionKind();
-                       ObjectFile::Atom::DefinitionKind existingDefKind = existingAtom->getDefinitionKind();
-                       if (newDefKind == ObjectFile::Atom::kRegularDefinition 
-                               && existingDefKind == ObjectFile::Atom::kRegularDefinition)
-                               throwf ("duplicate symbol %s in %s and %s\n", name, a->getFile()->getPath(), existingAtom->getFile()->getPath());
-                       else if (newDefKind == ObjectFile::Atom::kWeakDefinition 
-                                        && existingDefKind == ObjectFile::Atom::kRegularDefinition)
-                               insertNewAtom = false;
-                       else if (newDefKind == ObjectFile::Atom::kWeakDefinition 
-                                        && existingDefKind == ObjectFile::Atom::kWeakDefinition)
-                               // pick one
-                               insertNewAtom = false;
-                       else if (newDefKind == ObjectFile::Atom::kRegularDefinition 
-                                        && existingDefKind == ObjectFile::Atom::kWeakDefinition)
-                               insertNewAtom = true;
-               }
-               if (insertNewAtom) {
-                       atoms.push_back(a);
-                       fLLVMSymbols[name] = a;
-                       a->addReference(new LLVMReference (intercessorName));
-               }
-       }
-}
-
-void LLVMOptimizer::reconcileOptimizedAtoms(std::vector<class ObjectFile::Atom*>& optimizedAtoms,
-                                                                                       std::vector<class ObjectFile::Atom*>& newAtoms)
-{
-       for (std::vector<ObjectFile::Atom *>::iterator itr = optimizedAtoms.begin(); 
-                itr != optimizedAtoms.end(); ++itr) {
-
-               ObjectFile::Atom* atom = *itr;
-               if (!atom->getName()) {
-                       newAtoms.push_back(atom);
-                       continue;
-               }
-
-               LLVMAtomToNameMapper::iterator pos = fLLVMSymbols.find(atom->getName());
-               if ( pos != fLLVMSymbols.end() ) {
-
-                       LLVMAtom *la = fLLVMSymbols[atom->getName()];
-                       la->setRealAtom(atom);
-
-               } 
-               else
-                       newAtoms.push_back(atom);
-       }
-}
-
-//
-// LLVM bytecode file reader
-//
-
-class LLVMReader : public ObjectFile::Reader
-{
-public:
-       static bool                                                                             validFile(const uint8_t* fileContent, const char *path, cpu_type_t architecture, Options &opts);
-       static LLVMReader*                                                              make(const uint8_t* fileContent, const char* path, time_t modTime, Options& options) 
-                                                                                                                                                       { return new LLVMReader(fileContent, path, modTime, options); }
-       virtual                                                                                 ~LLVMReader();
-       virtual std::vector<class ObjectFile::Atom*>&   getAtoms()                              { return (std::vector<class ObjectFile::Atom*>&)(fAtoms); }
-       virtual std::vector<class ObjectFile::Atom*>*   getJustInTimeAtomsFor(const char* name) { return NULL; }
-       virtual const char*                                                             getPath()                               { return fPath; }
-       virtual time_t                                                                  getModificationTime()   { return fModTime; }
-       virtual ObjectFile::Reader::DebugInfoKind               getDebugInfoKind()              { return kDebugInfoNone; }
-       virtual std::vector<Stab>*                                              getStabs()                              { return NULL; }
-
-       ObjectFile::Atom *                                                              retriveIntercessorAtom()        { fAtoms.pop_back();return fIntercessorAtom; }
-       ObjectFile::Atom *                                                              getIntercessorAtom()    { return fIntercessorAtom; }
-
-private:
-
-                                                                                                       LLVMReader(const uint8_t* fileContent, const char* path, time_t modTime, Options& options);
-       void                                                                                    optimize(std::vector<ObjectFile::Atom*>& allAtoms, std::vector<ObjectFile::Atom*> &newAtoms, uint32_t);
-       
-       const char*                                                                             fPath;
-       time_t                                                                                  fModTime;
-       std::vector<ObjectFile::Atom*>                                  fAtoms;
-       IntercessorAtom *                                                               fIntercessorAtom;
-       static LLVMOptimizer                                                    *fOptimizer;
-       std::set<std::string>                                                   fLLVMReferences;
-};
-
-LLVMOptimizer  *LLVMReader::fOptimizer = NULL;
-
-LLVMReader::~LLVMReader()
-{
-       if (fOptimizer)
-               delete fOptimizer;
-}
-
-LLVMReader::LLVMReader (const uint8_t* fileContent, const char *path, time_t modTime, Options& options)
-{
-
-       fPath = path;
-       fModTime = modTime;
-       fIntercessorAtom = new IntercessorAtom(this, fLLVMReferences);
-       fOptimizer->read(this, path, fLLVMReferences, fAtoms, fIntercessorAtom->getName());
-       fIntercessorAtom->addReferences(fLLVMReferences);
-       fAtoms.push_back(fIntercessorAtom);
-       fOptimizer->addIntercessor(fIntercessorAtom);
-       fOptimizer->addReader(this);
-}
-
-bool LLVMReader::validFile(const uint8_t* fileContent, const char *path, cpu_type_t architecture, Options &opts)
-{
-       if (fileContent[0] == 'l'
-               && fileContent[1] == 'l'
-               && fileContent[2] == 'v'
-               && (fileContent[3] == 'c' || fileContent[3] == 'm')) {
-
-               // create optimizer
-               if (!fOptimizer)
-                       fOptimizer = new LLVMOptimizer(opts);
-
-               if (fOptimizer->validArchitecture(path, architecture))
-                       return true;
-       }
-               
-       return false;
-}
-
-void LLVMReader::optimize(std::vector<ObjectFile::Atom *> &allAtoms, std::vector<ObjectFile::Atom*> &newAtoms, uint32_t nextInputOrdinal)
-{ 
-       if (fOptimizer)  
-               fOptimizer->optimize(allAtoms, newAtoms, nextInputOrdinal);
-}
-
-#endif
-
diff --git a/src/LTOReader.hpp b/src/LTOReader.hpp
new file mode 100755 (executable)
index 0000000..4cd5644
--- /dev/null
@@ -0,0 +1,642 @@
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
+ *
+ * Copyright (c) 2006-2008 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@
+ */
+
+#ifndef __LTO_READER_H__
+#define __LTO_READER_H__
+
+#include <stdlib.h>
+#include <mach-o/dyld.h>
+#include <vector>
+#include <ext/hash_set>
+#include <ext/hash_map>
+
+#include "MachOFileAbstraction.hpp"
+#include "Architectures.hpp"
+#include "ObjectFile.h"
+#include "Options.h"
+
+#include "llvm-c/lto.h"
+
+
+namespace lto {
+
+
+//
+// Reference handles Atom references. These references facilitate 
+// symbol resolution.
+//
+
+class Reference : public ObjectFile::Reference
+{
+public:
+                                                                               Reference(const char* name) : fTargetName(name), fTargetAtom(NULL) { }
+                                                                               Reference(ObjectFile::Atom& atom) : fTargetName(NULL), fTargetAtom(&atom) { }
+
+       bool                                                            isTargetUnbound() const                         { return fTargetAtom == NULL; }
+       bool                                                            isFromTargetUnbound() const             { return true; }
+       uint8_t                                                         getKind() const                                         { return 0; }
+       uint64_t                                                        getFixUpOffset() const                          { return 0; }
+       const char *                                            getTargetName() const                           { return fTargetName; }
+       ObjectFile::Atom&                                       getTarget() const                                       { return *fTargetAtom; }
+       uint64_t                                                        getTargetOffset() const                         { return 0; }
+       bool                                                            hasFromTarget() const                           { return false; }
+       ObjectFile::Atom&                                       getFromTarget() const                           { return *((ObjectFile::Atom*)NULL); }
+       const char *                                            getFromTargetName() const                       { return NULL; }
+       uint64_t                                                        getFromTargetOffset() const             { return 0; }
+       TargetBinding                                           getTargetBinding() const;
+       TargetBinding                                           getFromTargetBinding() const  { return kDontBind; }
+       void                                                            setTarget (ObjectFile::Atom& a, uint64_t offset) 
+                                                                               { fTargetAtom = &a; }
+       void                                                            setFromTarget(ObjectFile::Atom &a)      { }
+       const char *                                            getDescription() const;
+
+private:
+       const char *                                            fTargetName;
+       ObjectFile::Atom *                                      fTargetAtom;
+};
+
+
+ObjectFile::Reference::TargetBinding Reference::getTargetBinding() const 
+{ 
+       if ( fTargetAtom == NULL ) 
+               return kUnboundByName;
+       else if ( fTargetName == NULL ) 
+               return kBoundDirectly;
+       else
+               return kBoundByName;
+}
+
+const char* Reference::getDescription() const
+{ 
+       static char temp[256];
+       strcpy(temp, "reference to ");
+       if ( fTargetName != NULL )
+               strcat(temp, fTargetName);
+       else
+               strcat(temp, fTargetAtom->getDisplayName());
+       return temp; 
+}
+
+
+class Segment : public ObjectFile::Segment
+{
+public:
+                                                                               Segment(const char* name, bool readable, bool writable, bool executable, bool fixedAddress)
+                                                                                       : fName(name), fReadable(readable), fWritable(writable), fExecutable(executable), fFixedAddress(fixedAddress) {}
+       virtual const char*                                     getName() const                                         { return fName; }
+       virtual bool                                            isContentReadable() const                       { return fReadable; }
+       virtual bool                                            isContentWritable() const                       { return fWritable; }
+       virtual bool                                            isContentExecutable() const                     { return fExecutable; }
+       virtual bool                                            hasFixedAddress() const                         { return fFixedAddress; }
+
+       static Segment                                          fgBootstrapSegment;
+
+private:
+       const char*                                                     fName;
+       const bool                                                      fReadable;
+       const bool                                                      fWritable;
+       const bool                                                      fExecutable;
+       const bool                                                      fFixedAddress;
+};
+
+Segment        Segment:: fgBootstrapSegment("__TEMP", true, false, false, false);
+  
+       
+         
+
+//
+// Atom acts as a proxy Atom for the symbols that are exported by LLVM bitcode file. Initially,
+// Reader creates Atoms to allow linker proceed with usual symbol resolution phase. After
+// optimization is performed, real Atoms are created for these symobls. However these real Atoms
+// are not inserted into global symbol table. Atom holds real Atom and forwards appropriate
+// methods to real atom.
+//
+class Atom : public ObjectFile::Atom
+{
+public:
+                                                                                               Atom(class Reader& owner, const char* name, Scope, DefinitionKind, uint8_t alignment, ObjectFile::Atom& internalAtom);
+       
+       ObjectFile::Reader*                                                     getFile() const                         { return (ObjectFile::Reader*)&fOwner; }
+       bool                                                                            getTranslationUnitSource (const char **dir, const char **name) const 
+                                                                                                                                                       { return fRealAtom->getTranslationUnitSource(dir, name); }
+       const char *                                                            getName () const                        { return fName; }
+       const char *                                                            getDisplayName() const          { return this->getName(); }
+       Scope                                                                           getScope() const                        { return fScope; }
+       DefinitionKind                                                          getDefinitionKind() const       { return (fRealAtom ? fRealAtom->getDefinitionKind() : fKind); }
+       SymbolTableInclusion                                            getSymbolTableInclusion() const 
+                                                                                                                                                       { return fRealAtom->getSymbolTableInclusion(); }
+       bool                                                                            dontDeadStrip() const           { return false; }
+       bool                                                                            isZeroFill() const                      { return (fRealAtom ? fRealAtom->isZeroFill() : false); }
+       bool                                                                            isThumb() const                         { return false; }
+       uint64_t                                                                        getSize() const                         { return (fRealAtom ? fRealAtom->getSize() : 0); }
+       std::vector<ObjectFile::Reference*>&            getReferences() const 
+                                                                                                                                                       { return (fRealAtom ? fRealAtom->getReferences() : (std::vector<ObjectFile::Reference*>&)fReferences); }
+       bool                                                                            mustRemainInSection() const { return fRealAtom->mustRemainInSection(); }
+       const char *                                                            getSectionName() const          { return (fRealAtom ? fRealAtom->getSectionName() : NULL); }
+       // Linker::optimize() sets section for this atom, not fRealAtom. Use this Atom's fSection.
+       class ObjectFile::Section *                                     getSection() const                      { return fSection; }
+       ObjectFile::Segment&                                            getSegment() const                      { return (fRealAtom ? fRealAtom->getSegment() : Segment::fgBootstrapSegment); }
+       uint32_t                                                                        getOrdinal() const                      { return (fRealAtom ? fRealAtom->getOrdinal() : 0); }
+       ObjectFile::Atom&                                                       getFollowOnAtom() const         { return fRealAtom->getFollowOnAtom(); }
+       std::vector<ObjectFile::LineInfo>*                      getLineInfo() const             { return (fRealAtom ? fRealAtom->getLineInfo() : NULL); }
+       ObjectFile::Alignment                                           getAlignment() const            { return (fRealAtom ? fRealAtom->getAlignment() : ObjectFile::Alignment(fAlignment)); }
+       void                                                                            copyRawContent(uint8_t buffer[]) const 
+                                                                                                                                                       { if (fRealAtom) fRealAtom->copyRawContent(buffer); }
+       void                                                                            setScope(Scope s)                       { if (fRealAtom) fRealAtom->setScope(s); else fScope = s; }
+
+       void                                                                            setRealAtom (ObjectFile::Atom *atom) 
+                                                                                                                                                       { fRealAtom = atom; }
+       ObjectFile::Atom *                                                      getRealAtom() { return fRealAtom; }
+       void                                                                            addReference(ObjectFile::Reference *ref) 
+                                                                                                                                                       { fReferences.push_back(ref); }
+
+       void                                                                            setSectionOffset(uint64_t offset) { fSectionOffset = offset; if (fRealAtom) fRealAtom->setSectionOffset(offset); }
+       void                                                                            setSection(class ObjectFile::Section* sect) { fSection = sect; if (fRealAtom) fRealAtom->setSection(sect); }
+                                                                                                                                                       
+private:
+       class Reader&                                                           fOwner;
+       const char*                                                                     fName;
+       ObjectFile::Atom::Scope                                         fScope;
+       ObjectFile::Atom::DefinitionKind                        fKind;
+       uint8_t                                                                         fAlignment;
+       ObjectFile::Atom*                                                       fRealAtom;
+       std::vector<ObjectFile::Reference*>             fReferences;
+};
+
+
+Atom::Atom(class Reader& owner, const char* name, Scope scope, DefinitionKind kind, uint8_t alignment, ObjectFile::Atom& internalAtom) 
+: fOwner(owner), fName(name), fScope(scope), fKind(kind), fAlignment(alignment), fRealAtom(NULL)
+{
+       // every Atom references the InternalAtom for its reader
+       fReferences.push_back(new Reference(internalAtom));
+}
+
+
+//
+// ld64 only tracks non-internal symbols from an llvm bitcode file.  
+// We model this by having an InternalAtom which represent all internal functions and data.
+// All non-interal symbols from a bitcode file are represented by a Atom
+// and each Atom has a reference to the InternalAtom.  The InternalAtom
+// also has references to each symbol external to the bitcode file. 
+//
+class InternalAtom : public ObjectFile::Atom
+{
+public:
+                                                                                               InternalAtom(class Reader& owner) : fOwner(owner) {}
+
+       ObjectFile::Reader *                                            getFile() const                         { return (ObjectFile::Reader*)&fOwner; }
+       bool                                                                            getTranslationUnitSource (const char **dir, const char **name) const 
+                                                                                                                                                       { return false; }
+       const char *                                                            getName () const                        { return "__llvm-internal-atom";        }
+       const char *                                                            getDisplayName() const          { return this->getName(); }
+       Scope                                                                           getScope() const                        { return scopeTranslationUnit; }
+       DefinitionKind                                                          getDefinitionKind() const   { return kRegularDefinition; }
+       SymbolTableInclusion                                            getSymbolTableInclusion() const { return kSymbolTableNotIn; }
+       bool                                                                            dontDeadStrip() const           { return false; }
+       bool                                                                            isZeroFill() const                      { return false; }
+       bool                                                                            isThumb() const                         { return false; }
+       uint64_t                                                                        getSize() const                         { return 0; }
+       std::vector<ObjectFile::Reference*>&            getReferences() const           { return  (std::vector<ObjectFile::Reference*>&)fReferences; }
+       bool                                                                            mustRemainInSection() const { return false; }
+       const char *                                                            getSectionName() const          { return NULL; }
+       class ObjectFile::Section *                                     getSection() const                      { return NULL; }
+       ObjectFile::Segment&                                            getSegment() const                      { return Segment::fgBootstrapSegment; }
+       uint32_t                                                                        getOrdinal() const          { return 0; }
+       ObjectFile::Atom&                                                       getFollowOnAtom() const         { return *((ObjectFile::Atom*)NULL); }
+       std::vector<ObjectFile::LineInfo>*                      getLineInfo() const             { return NULL; }
+       ObjectFile::Alignment                                           getAlignment() const            { return ObjectFile::Alignment(0); }
+       void                                                                            copyRawContent(uint8_t buffer[]) const { }
+       void                                                                            setScope(Scope s)                       { }
+
+       void                                                                            addReference(const char* targetName);
+       
+private:
+       class Reader&                                                   fOwner;
+       std::vector<ObjectFile::Reference*>             fReferences;
+};
+
+
+void InternalAtom::addReference(const char* name)
+{
+       fReferences.push_back(new Reference(name));
+}
+
+
+
+
+class RemovableAtoms
+{
+public:
+       RemovableAtoms(std::set<ObjectFile::Atom*>& iAtoms) : fAtoms(iAtoms) {}
+
+       bool operator()(ObjectFile::Atom*& atom) const {
+               return ( fAtoms.count(atom) != 0 );
+       }
+
+private:
+       std::set<ObjectFile::Atom*>& fAtoms;
+};
+
+
+
+//
+// LLVM bitcode file reader
+//
+class Reader : public ObjectFile::Reader
+{
+public:
+       static bool                                                                             validFile(const uint8_t* fileContent, uint64_t fileLength, cpu_type_t architecture);
+       static bool                                                                             loaded() { return (::lto_get_version() != NULL); }
+                                                                                                       Reader(const uint8_t* fileContent, uint64_t fileLength, 
+                                                                                                                               const char* path, time_t modTime, 
+                                                                                                                               const ObjectFile::ReaderOptions&, cpu_type_t arch);
+       virtual                                                                                 ~Reader();
+       
+       virtual std::vector<class ObjectFile::Atom*>&   getAtoms()                              { return (std::vector<class ObjectFile::Atom*>&)(fAtoms); }
+       virtual std::vector<class ObjectFile::Atom*>*   getJustInTimeAtomsFor(const char* name) { return NULL; }
+       virtual const char*                                                             getPath()                               { return fPath; }
+       virtual time_t                                                                  getModificationTime()   { return fModTime; }
+       virtual ObjectFile::Reader::DebugInfoKind               getDebugInfoKind()              { return kDebugInfoNone; }
+       virtual std::vector<Stab>*                                              getStabs()                              { return NULL; }
+       virtual void                                                                    optimize(std::vector<ObjectFile::Atom*> &allAtoms, std::vector<ObjectFile::Atom*> &newAtoms, 
+                                                                                                                               std::vector<const char*> &additionalUndefines, uint32_t nextInputOrdinal, 
+                                                                                                                               ObjectFile::Reader* writer, bool allGlobalsAReDeadStripRoots,
+                                                                                                                               int outputKind, bool verbose, bool saveTemps, const char* outputFilePath,
+                                                                                                                               bool pie, bool allowTextRelocs);
+
+private:
+
+       class CStringEquals
+       {
+       public:
+               bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); }
+       };
+       typedef __gnu_cxx::hash_set<const char*, __gnu_cxx::hash<const char*>, CStringEquals>  CStringSet;
+       typedef __gnu_cxx::hash_map<const char*, Atom*, __gnu_cxx::hash<const char*>, CStringEquals> CStringToAtom;
+       
+       ObjectFile::Reader*                                                             makeMachOReader(const uint8_t* p, size_t len, uint32_t nextInputOrdinal);
+       static const char*                                                              tripletPrefixForArch(cpu_type_t);
+
+       cpu_type_t                                                                              fArchitecture;
+       const char*                                                                             fPath;
+       time_t                                                                                  fModTime;
+       lto_module_t                                                                    fModule;
+       std::vector<ObjectFile::Atom*>                                  fAtoms;
+       InternalAtom                                                                    fInternalAtom;
+       const ObjectFile::ReaderOptions&                                fReaderOptions;
+       static std::set<Reader*>                                                fgReaders;
+       static bool                                                                             fgOptimized;
+};
+
+bool                                   Reader::fgOptimized = false;
+std::set<Reader*>              Reader::fgReaders;
+
+
+Reader::~Reader()
+{
+       if ( fModule != NULL )
+               ::lto_module_dispose(fModule);
+}
+
+Reader::Reader(const uint8_t* fileContent, uint64_t fileLength, const char* path, time_t modTime, 
+                               const ObjectFile::ReaderOptions& options, cpu_type_t arch)
+       : fArchitecture(arch), fPath(path), fModTime(modTime), fInternalAtom(*this), fReaderOptions(options)
+{
+       fgReaders.insert(this);
+
+       fModule = ::lto_module_create_from_memory(fileContent, fileLength);
+    if ( fModule == NULL )
+               throwf("could not parse object file %s: %s", path, lto_get_error_message());
+       
+       
+       uint32_t count = ::lto_module_get_num_symbols(fModule);
+       for (uint32_t i=0; i < count; ++i) {
+               const char* name = ::lto_module_get_symbol_name(fModule, i);
+               lto_symbol_attributes attr = lto_module_get_symbol_attribute(fModule, i);
+               
+               ObjectFile::Atom::DefinitionKind kind;
+               switch ( attr & LTO_SYMBOL_DEFINITION_MASK ) {
+                       case LTO_SYMBOL_DEFINITION_REGULAR:
+                               kind = ObjectFile::Atom::kRegularDefinition;
+                               break;
+                       case LTO_SYMBOL_DEFINITION_TENTATIVE:
+                               kind = ObjectFile::Atom::kTentativeDefinition;
+                               break;
+                       case LTO_SYMBOL_DEFINITION_WEAK:
+                               kind = ObjectFile::Atom::kWeakDefinition;
+                               break;
+                       case LTO_SYMBOL_DEFINITION_UNDEFINED:
+                               kind = ObjectFile::Atom::kExternalDefinition;
+                               break;
+                       default:
+                               throwf("unknown definition kind for symbol %s in bitcode file %s", name, path);
+               }
+
+               // make LLVM atoms for definitions and a reference for undefines
+               if ( kind != ObjectFile::Atom::kExternalDefinition ) {
+                       ObjectFile::Atom::Scope scope;
+                       switch ( attr & LTO_SYMBOL_SCOPE_MASK) {
+                               case LTO_SYMBOL_SCOPE_INTERNAL:
+                                       scope = ObjectFile::Atom::scopeTranslationUnit;
+                                       break;
+                               case LTO_SYMBOL_SCOPE_HIDDEN:
+                                       scope = ObjectFile::Atom::scopeLinkageUnit;
+                                       break;
+                               case LTO_SYMBOL_SCOPE_DEFAULT:
+                                       scope = ObjectFile::Atom::scopeGlobal;
+                                       break;
+                               default:
+                                       throwf("unknown scope for symbol %s in bitcode file %s", name, path);
+                       }
+                       // only make atoms for non-internal symbols 
+                       if ( scope == ObjectFile::Atom::scopeTranslationUnit )
+                               continue;
+                       uint8_t alignment = (attr & LTO_SYMBOL_ALIGNMENT_MASK);
+                       // make Atom
+                       fAtoms.push_back(new Atom(*this, name, scope, kind, alignment, fInternalAtom));
+               }
+               else {
+                       // add to list of external references
+                       fInternalAtom.addReference(name);
+               }
+       }
+}
+
+const char* Reader::tripletPrefixForArch(cpu_type_t arch)
+{
+       switch (arch) {
+               case CPU_TYPE_POWERPC:
+                       return "powerpc-";
+               case CPU_TYPE_POWERPC64:
+                       return "powerpc64-";
+               case CPU_TYPE_I386:
+                       return "i386-";
+               case CPU_TYPE_X86_64:
+                       return "x86_64-";
+               case CPU_TYPE_ARM:
+                       return "arm-";
+       }
+       return "";
+}
+
+bool Reader::validFile(const uint8_t* fileContent, uint64_t fileLength, cpu_type_t architecture)
+{
+       return ::lto_module_is_object_file_in_memory_for_target(fileContent, fileLength, tripletPrefixForArch(architecture));
+}
+
+void Reader::optimize(std::vector<ObjectFile::Atom *>& allAtoms, std::vector<ObjectFile::Atom*>& newAtoms, 
+                                                       std::vector<const char*>& additionalUndefines, uint32_t nextInputOrdinal, 
+                                                       ObjectFile::Reader* writer, bool allGlobalsAReDeadStripRoots,
+                                                       int okind, bool verbose, bool saveTemps, const char* outputFilePath,
+                                                       bool pie, bool allowTextRelocs)
+{ 
+       // this method is call on all Readers.  We want the first call to trigger optimization
+       // across all Readers and the subsequent calls to do nothing.
+       if ( fgOptimized ) 
+               return;
+       fgOptimized = true;
+       
+       Options::OutputKind outputKind = (Options::OutputKind)okind; // HACK to work around upward dependency
+
+       // print out LTO version string if -v was used
+       if ( verbose )
+               fprintf(stderr, "%s\n", lto_get_version());
+       
+       // create optimizer and add each Reader
+       lto_code_gen_t generator = ::lto_codegen_create();
+       for (std::set<Reader*>::iterator it=fgReaders.begin(); it != fgReaders.end(); ++it) {
+               if ( ::lto_codegen_add_module(generator, (*it)->fModule) )
+                       throwf("lto: could not merge in %s", (*it)->fPath);
+       }
+
+       // the linker must preserve all globals in dylibs and flat images
+       const bool globalsNeedPreserving = allGlobalsAReDeadStripRoots || fReaderOptions.fFlatNamespace;
+       
+       // The atom graph uses directed edges (references). Collect all references where 
+       // originating atom is not part of any LTO Reader. This allows optimizer to optimize an 
+       // external (i.e. not originated from same .o file) reference if all originating atoms are also 
+       // defined in llvm bitcode file.
+       CStringSet nonLLVMRefs;
+       CStringToAtom llvmAtoms;
+    bool hasNonllvmAtoms = false;
+       for (std::vector<ObjectFile::Atom*>::iterator it = allAtoms.begin(); it != allAtoms.end(); ++it) {
+               ObjectFile::Atom* atom = *it;
+               // only look at references come from an atom that is not an llvm atom
+               if ( fgReaders.count((Reader*)(atom->getFile())) == 0 ) {
+                               // remember if we've seen an atoms not from an llvm reader and not from the writer
+                               if ( atom->getFile() != writer )
+                                       hasNonllvmAtoms = true;
+                               std::vector<ObjectFile::Reference*>& refs = atom->getReferences();
+                               for (std::vector<ObjectFile::Reference*>::iterator ri=refs.begin(), re=refs.end(); ri != re; ++ri) {
+                                       ObjectFile::Reference* ref = *ri;
+                                       // add target name to set if target is an llvm atom
+                                       if ( (ref->getTargetName() != NULL) && (fgReaders.count((Reader*)(ref->getTarget().getFile())) != 0) ) {
+                                               nonLLVMRefs.insert(ref->getTargetName());
+                               }
+                       }
+               }
+               else {
+                       const char* name = atom->getName();
+                       if ( name != NULL )
+                               llvmAtoms[name] = (Atom*)atom;
+               }
+       }
+       // tell code generator about symbols that must be preserved
+       for (CStringToAtom::iterator it = llvmAtoms.begin(); it != llvmAtoms.end(); ++it) {
+               const char* name = it->first;
+               Atom* atom = it->second;
+               // Include llvm Symbol in export list if it meets one of following two conditions
+               // 1 - globals need preserving and atom scope is global (and not linkage unit).
+               // 2 - included in nonLLVMRefs set.
+               // If a symbol is not listed in exportList then LTO is free to optimize it away.
+               if ( globalsNeedPreserving && (atom->getScope() == ObjectFile::Atom::scopeGlobal) )
+                       ::lto_codegen_add_must_preserve_symbol(generator, name);
+               else if ( nonLLVMRefs.find(name) != nonLLVMRefs.end() )
+                       ::lto_codegen_add_must_preserve_symbol(generator, name);
+       }
+       
+    // special case running ld -r on all bitcode files to produce another bitcode file (instead of mach-o)
+    if ( (outputKind == Options::kObjectFile) && !hasNonllvmAtoms ) {
+               if ( ! ::lto_codegen_write_merged_modules(generator, outputFilePath) ) {
+                       // HACK, no good way to tell linker we are all done, so just quit
+                       exit(0);
+               }
+               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 ) {
+               case Options::kDynamicExecutable:
+                       if ( pie )
+                               model = LTO_CODEGEN_PIC_MODEL_DYNAMIC;
+                       else
+                               model = LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC;
+                       break;
+               case Options::kDynamicLibrary:
+               case Options::kDynamicBundle:
+               case Options::kObjectFile: // ?? Is this appropriate ?
+               case Options::kDyld:
+                       if ( allowTextRelocs )
+                               model = LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC;
+                       else
+                               model = LTO_CODEGEN_PIC_MODEL_DYNAMIC;
+                       break;
+               case Options::kStaticExecutable:
+                       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());
+
+       // run code generator
+       size_t machOFileLen;
+       const uint8_t* machOFile = (uint8_t*)::lto_codegen_compile(generator, &machOFileLen);
+       if ( machOFile == NULL ) 
+               throwf("could not do LTO codegen: %s", ::lto_get_error_message());
+       
+    // if requested, save off temp mach-o file
+    if ( saveTemps ) {
+        char tempMachoPath[MAXPATHLEN];
+        strcpy(tempMachoPath, outputFilePath);
+        strcat(tempMachoPath, ".lto.o");
+        int fd = ::open(tempMachoPath, O_CREAT | O_WRONLY | O_TRUNC, 0666);
+               if ( fd != -1) {
+                       ::write(fd, machOFile, machOFileLen);
+                       ::close(fd);
+               }
+    }
+
+       // parse generated mach-o file into a MachOReader
+       ObjectFile::Reader* machoReader = this->makeMachOReader(machOFile, machOFileLen, nextInputOrdinal);
+       
+       // sync generated mach-o atoms with existing atoms ld know about
+       std::vector<ObjectFile::Atom*> machoAtoms = machoReader->getAtoms();
+       for (std::vector<ObjectFile::Atom *>::iterator it = machoAtoms.begin(); it != machoAtoms.end(); ++it) {
+               ObjectFile::Atom* atom = *it;
+               const char* name = atom->getName();
+               if ( name != NULL ) {
+                       CStringToAtom::iterator pos = llvmAtoms.find(name);
+                       if ( pos != llvmAtoms.end() ) {
+                               // turn Atom into a proxy for this mach-o atom
+                               pos->second->setRealAtom(atom);
+                       }
+                       else {
+                               // this atom is did not exist orginally, tell ld about it
+                               newAtoms.push_back(atom);
+                       }
+               }
+               else {
+                       // ld only knew about named atoms, so this one must be new
+                       newAtoms.push_back(atom);
+               }
+               std::vector<class ObjectFile::Reference*>& references = atom->getReferences();
+               for (std::vector<ObjectFile::Reference*>::iterator rit=references.begin(); rit != references.end(); ++rit) {
+                       ObjectFile::Reference* ref = *rit;
+                       const char* targetName = ref->getTargetName();
+                       CStringToAtom::iterator pos;
+                       if (targetName != NULL) {
+                               switch ( ref->getTargetBinding() ) {
+                                       case ObjectFile::Reference::kUnboundByName:
+                                               // accumulate unbounded references so that ld can bound them.
+                                               additionalUndefines.push_back(targetName);
+                                               break;
+                                       case ObjectFile::Reference::kBoundDirectly:
+                                       case ObjectFile::Reference::kBoundByName:
+                                               // If mach-o atom is referencing another mach-o atom then 
+                                               // reference is not going through Atom proxy. Fix it here to ensure that all
+                                               // llvm symbol references always go through Atom proxy.
+                                               pos = llvmAtoms.find(targetName);
+                                               if ( pos != llvmAtoms.end() )
+                                                       ref->setTarget(*pos->second, ref->getTargetOffset());
+                                               break;
+                                       case ObjectFile::Reference::kDontBind:
+                                               break;
+                               }
+                       }
+               }
+       }
+               
+       // Remove InternalAtoms from ld
+       std::set<class ObjectFile::Atom*> deletedAtoms;
+       for (std::set<Reader*>::iterator it=fgReaders.begin(); it != fgReaders.end(); ++it) {
+               deletedAtoms.insert(&((*it)->fInternalAtom));
+       }
+       // Remove Atoms from ld if code generator optimized them away
+       for (CStringToAtom::iterator li = llvmAtoms.begin(), le = llvmAtoms.end(); li != le; ++li) {
+               // check if setRealAtom() called on this Atom
+               if ( li->second->getRealAtom() == NULL )
+                       deletedAtoms.insert(li->second);
+       }
+       allAtoms.erase(std::remove_if(allAtoms.begin(), allAtoms.end(), RemovableAtoms(deletedAtoms)), allAtoms.end());
+}
+
+
+ObjectFile::Reader* Reader::makeMachOReader(const uint8_t* p, size_t len, uint32_t nextInputOrdinal) 
+{
+       switch ( fArchitecture ) {
+               case CPU_TYPE_POWERPC:
+                       if ( mach_o::relocatable::Reader<ppc>::validFile(p) )
+                               return new mach_o::relocatable::Reader<ppc>(p, "/tmp/lto.o", 0, fReaderOptions, nextInputOrdinal);
+                       break;
+               case CPU_TYPE_POWERPC64:
+                       if ( mach_o::relocatable::Reader<ppc64>::validFile(p) )
+                               return new mach_o::relocatable::Reader<ppc64>(p, "/tmp/lto.o", 0, fReaderOptions, nextInputOrdinal);
+                       break;
+               case CPU_TYPE_I386:
+                       if ( mach_o::relocatable::Reader<x86>::validFile(p) )
+                               return new mach_o::relocatable::Reader<x86>(p, "/tmp/lto.o", 0, fReaderOptions, nextInputOrdinal);
+                       break;
+               case CPU_TYPE_X86_64:
+                       if ( mach_o::relocatable::Reader<x86_64>::validFile(p) )
+                               return new mach_o::relocatable::Reader<x86_64>(p, "/tmp/lto.o", 0, fReaderOptions, nextInputOrdinal);
+                       break;
+               case CPU_TYPE_ARM:
+                       if ( mach_o::relocatable::Reader<arm>::validFile(p) )
+                               return new mach_o::relocatable::Reader<arm>(p, "/tmp/lto.o", 0, fReaderOptions, nextInputOrdinal);
+                       break;
+       }
+       throw "LLVM LTO, file is not of required architecture";
+}
+
+}; // namespace lto
+
+
+void printLTOVersion(Options &opts) {
+       const char* vers = lto_get_version();
+       if ( vers != NULL )
+               fprintf(stderr, "%s\n", vers);
+}
+
+
+#endif
+
old mode 100644 (file)
new mode 100755 (executable)
index e0f5620..83a8ee1
@@ -1,6 +1,6 @@
 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
  *
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2005-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include <mach-o/loader.h>
 #include <mach-o/nlist.h>
 #include <mach-o/reloc.h>
+#include <mach-o/fat.h>
+#include <mach-o/stab.h>
+#include <mach-o/reloc.h>
+#include <mach-o/ppc/reloc.h>
+#include <mach-o/x86_64/reloc.h>
 #include <mach/machine.h>
 
-// suport older versions of mach-o/loader.h
-#ifndef LC_UUID
-#define LC_UUID                0x1b
-struct uuid_command {
-    uint32_t   cmd;            /* LC_UUID */
-    uint32_t   cmdsize;        /* sizeof(struct uuid_command) */
-    uint8_t    uuid[16];       /* the 128-bit uuid */
-};
-#endif
-
-#ifndef S_16BYTE_LITERALS
-       #define S_16BYTE_LITERALS 0xE
-#endif
-
 #include "FileAbstraction.hpp"
 #include "Architectures.hpp"
 
+// stuff that will eventually go away once newer cctools headers are widespread
+#ifndef LC_LAZY_LOAD_DYLIB
+       #define LC_LAZY_LOAD_DYLIB  0x20
+#endif
+#ifndef S_LAZY_DYLIB_SYMBOL_POINTERS
+       #define S_LAZY_DYLIB_SYMBOL_POINTERS  0x10
+#endif
+#ifndef CPU_SUBTYPE_ARM_V5TEJ
+       #define CPU_SUBTYPE_ARM_V5TEJ           ((cpu_subtype_t) 7)
+#endif
+#ifndef CPU_SUBTYPE_ARM_XSCALE
+       #define CPU_SUBTYPE_ARM_XSCALE          ((cpu_subtype_t) 8)
+#endif
+#ifndef CPU_SUBTYPE_ARM_V7
+       #define CPU_SUBTYPE_ARM_V7                      ((cpu_subtype_t) 9)
+#endif
+#ifndef N_ARM_THUMB_DEF
+       #define N_ARM_THUMB_DEF 0x0008 
+#endif
+enum reloc_type_arm
+{
+    ARM_RELOC_VANILLA, /* generic relocation as discribed above */
+    ARM_RELOC_PAIR,    /* the second relocation entry of a pair */
+    ARM_RELOC_SECTDIFF,        /* a PAIR follows with subtract symbol value */
+    ARM_RELOC_LOCAL_SECTDIFF, /* like ARM_RELOC_SECTDIFF, but the symbol
+                                referenced was local.  */
+    ARM_RELOC_PB_LA_PTR,/* prebound lazy pointer */
+    ARM_RELOC_BR24,    /* 24 bit branch displacement (to a word address) */
+    ARM_THUMB_RELOC_BR22, /* 22 bit branch displacement (to a half-word
+                            address) */
+};
+
+#ifndef LC_ENCRYPTION_INFO
+       #define LC_ENCRYPTION_INFO              0x21
+       struct encryption_info_command {
+               uint32_t        cmd;
+               uint32_t        cmdsize;
+               uint32_t        cryptoff;       /* file offset of encrypted range */
+               uint32_t        cryptsize;      /* file size of encrypted range */
+               uint32_t        cryptid;        /* which enryption system, 0 means not-encrypted yet */
+       };
+#endif
 
 
 //
@@ -724,7 +757,7 @@ public:
        
        typedef typename P::E           E;
 private:
-       linkedit_data_command   fields;
+       struct linkedit_data_command    fields;
 };
 
 
@@ -749,7 +782,7 @@ public:
        
        typedef typename P::E           E;
 private:
-       rpath_command   fields;
+       struct rpath_command    fields;
 };
 
 
@@ -859,6 +892,31 @@ private:
 
 
 
+//
+// mach-o encyrption info load command
+//
+template <typename P>
+class macho_encryption_info_command {
+public:
+       uint32_t                cmd() const                                             INLINE { return E::get32(fields.cmd); }
+       void                    set_cmd(uint32_t value)                 INLINE { E::set32(fields.cmd, value); }
+
+       uint32_t                cmdsize() const                                 INLINE { return E::get32(fields.cmdsize); }
+       void                    set_cmdsize(uint32_t value)             INLINE { E::set32(fields.cmdsize, value); }
+
+       uint32_t                cryptoff() const                                INLINE { return E::get32(fields.cryptoff); }
+       void                    set_cryptoff(uint32_t value)    INLINE { E::set32(fields.cryptoff, value);  }
+       
+       uint32_t                cryptsize() const                               INLINE { return E::get32(fields.cryptsize); }
+       void                    set_cryptsize(uint32_t value)   INLINE { E::set32(fields.cryptsize, value);  }
+       
+       uint32_t                cryptid() const                                 INLINE { return E::get32(fields.cryptid); }
+       void                    set_cryptid(uint32_t value)             INLINE { E::set32(fields.cryptid, value);  }
+       
+       typedef typename P::E           E;
+private:
+       encryption_info_command fields;
+};
 
 
 
diff --git a/src/MachOReaderArchive.hpp b/src/MachOReaderArchive.hpp
deleted file mode 100644 (file)
index c01a603..0000000
+++ /dev/null
@@ -1,388 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
- *
- * Copyright (c) 2005-2006 Apple Computer, 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@
- */
-
-#ifndef __OBJECT_FILE_ARCHIVE_MACH_O__
-#define __OBJECT_FILE_ARCHIVE_MACH_O__
-
-#include <stdint.h>
-#include <math.h>
-#include <unistd.h>
-#include <sys/param.h>
-#include <mach-o/ranlib.h>
-#include <ar.h>
-
-#include <vector>
-#include <set>
-#include <algorithm>
-#include <ext/hash_map>
-
-#include "MachOFileAbstraction.hpp"
-#include "ObjectFile.h"
-#include "MachOReaderRelocatable.hpp"
-
-
-namespace mach_o {
-namespace archive {
-
-typedef const struct ranlib* ConstRanLibPtr;
-
-template <typename A>
-class Reader : public ObjectFile::Reader
-{
-public:
-       static bool                                                                             validFile(const uint8_t* fileContent, uint64_t fileLength);
-                                                                                                       Reader(const uint8_t fileContent[], uint64_t fileLength,
-                                                                                                                       const char* path, time_t modTime, 
-                                                                                                                       const ObjectFile::ReaderOptions& options, uint32_t ordinalBase);
-       virtual                                                                                 ~Reader() {}
-
-       virtual const char*                                                             getPath()                       { return fPath; }
-       virtual time_t                                                                  getModificationTime(){ return fModTime; }
-       virtual DebugInfoKind                                                   getDebugInfoKind()      { return ObjectFile::Reader::kDebugInfoNone; }
-       virtual std::vector<class ObjectFile::Atom*>&   getAtoms();
-       virtual std::vector<class ObjectFile::Atom*>*   getJustInTimeAtomsFor(const char* name);
-       virtual std::vector<Stab>*                                              getStabs()                      { return NULL; }
-
-private:
-       class Entry : ar_hdr
-       {
-       public:
-               const char*                     getName() const;
-               time_t                          getModTime() const;
-               const uint8_t*          getContent() const;
-               uint32_t                        getContentSize() const;
-               const Entry*            getNext() const;
-       private:
-               bool                            hasLongName() const;
-               unsigned int            getLongNameSpace() const;
-
-       };
-
-       class CStringEquals
-       {
-       public:
-               bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); }
-       };
-       typedef __gnu_cxx::hash_map<const char*, const struct ranlib*, __gnu_cxx::hash<const char*>, CStringEquals> NameToEntryMap;
-
-       typedef typename A::P                                                   P;
-       typedef typename A::P::E                                                E;
-
-       const struct ranlib*                                                    ranlibHashSearch(const char* name);
-       ObjectFile::Reader*                                                             makeObjectReaderForMember(const Entry* member);
-       void                                                                                    dumpTableOfContents();
-       void                                                                                    buildHashTable();
-
-       const char*                                                                             fPath;
-       time_t                                                                                  fModTime;
-       const ObjectFile::ReaderOptions&                                fOptions;
-       uint32_t                                                                                fOrdinalBase;
-       const uint8_t*                                                                  fFileContent;
-       uint64_t                                                                                fFileLength;
-       const struct ranlib*                                                    fTableOfContents;
-       uint32_t                                                                                fTableOfContentCount;
-       const char*                                                                             fStringPool;
-       std::vector<class ObjectFile::Atom*>                    fAllAtoms;
-       std::set<const class Entry*>                                    fInstantiatedEntries;
-       std::set<const class Entry*>                                    fPossibleEntries;
-       NameToEntryMap                                                                  fHashTable;
-
-       static std::vector<class ObjectFile::Atom*>             fgEmptyList;
-};
-
-template <typename A>
-std::vector<class ObjectFile::Atom*>           Reader<A>::fgEmptyList;
-
-
-template <typename A>
-bool Reader<A>::Entry::hasLongName() const
-{
-       return ( strncmp(this->ar_name, AR_EFMT1, strlen(AR_EFMT1)) == 0 );
-}
-
-template <typename A>
-unsigned int Reader<A>::Entry::getLongNameSpace() const
-{
-       char* endptr;
-       long result = strtol(&this->ar_name[strlen(AR_EFMT1)], &endptr, 10);
-       return result;
-}
-
-template <typename A>
-const char* Reader<A>::Entry::getName() const
-{
-       if ( this->hasLongName() ) {
-               int len = this->getLongNameSpace();
-               static char longName[256];
-               strncpy(longName, ((char*)this)+sizeof(ar_hdr), len);
-               longName[len] = '\0';
-               return longName;
-       }
-       else {
-               static char shortName[20];
-               strncpy(shortName, this->ar_name, 16);
-               shortName[16] = '\0';
-               char* space = strchr(shortName, ' ');
-               if ( space != NULL )
-                       *space = '\0';
-               return shortName;
-       }
-}
-
-template <typename A>
-time_t Reader<A>::Entry::getModTime() const
-{
-       char temp[14];
-       strncpy(temp, this->ar_date, 12);
-       temp[12] = '\0';
-       char* endptr;
-       return (time_t)strtol(temp, &endptr, 10);
-}
-
-
-template <typename A>
-const uint8_t* Reader<A>::Entry::getContent() const
-{
-       if ( this->hasLongName() )
-               return ((uint8_t*)this) + sizeof(ar_hdr) + this->getLongNameSpace();
-       else
-               return ((uint8_t*)this) + sizeof(ar_hdr);
-}
-
-
-template <typename A>
-uint32_t Reader<A>::Entry::getContentSize() const
-{
-       char temp[12];
-       strncpy(temp, this->ar_size, 10);
-       temp[10] = '\0';
-       char* endptr;
-       long size = strtol(temp, &endptr, 10);
-       // long name is included in ar_size
-       if ( this->hasLongName() )
-               size -= this->getLongNameSpace();
-       return size;
-}
-
-
-template <typename A>
-const class Reader<A>::Entry* Reader<A>::Entry::getNext() const
-{
-       const uint8_t* p = this->getContent() + getContentSize();
-       p = (const uint8_t*)(((uintptr_t)p+3) & (-4));  // 4-byte align
-       return (class Reader<A>::Entry*)p;
-}
-
-template <typename A>
-bool Reader<A>::validFile(const uint8_t* fileContent, uint64_t fileLength)
-{
-       // must have valid archive header
-       if ( strncmp((const char*)fileContent, "!<arch>\n", 8) != 0 )
-               return false;
-               
-       // peak at first .o file and verify it is correct architecture
-       const Entry* const start = (Entry*)&fileContent[8];
-       const Entry* const end = (Entry*)&fileContent[fileLength];
-       for (const Entry* p=start; p < end; p = p->getNext()) {
-               const char* memberName = p->getName();
-               // skip option table-of-content member
-               if ( (p==start) && ((strcmp(memberName, SYMDEF_SORTED) == 0) || (strcmp(memberName, SYMDEF) == 0)) )
-                       continue;
-               // archive is valid if first .o file is valid
-               return mach_o::relocatable::Reader<A>::validFile(p->getContent());
-       }       
-       // empty archive
-       return true;
-}
-
-template <typename A>
-Reader<A>::Reader(const uint8_t fileContent[], uint64_t fileLength, const char* path, time_t modTime, 
-                                       const ObjectFile::ReaderOptions& options, uint32_t ordinalBase)
- : fPath(NULL), fModTime(modTime), fOptions(options), fOrdinalBase(ordinalBase), fFileContent(NULL), 
-       fTableOfContents(NULL), fTableOfContentCount(0), fStringPool(NULL)
-{
-       fPath = strdup(path);
-       fFileContent = fileContent;
-       fFileLength = fileLength;
-
-       if ( strncmp((const char*)fileContent, "!<arch>\n", 8) != 0 )
-               throw "not an archive";
-
-       // write out path for -whatsloaded option
-       if ( options.fLogAllFiles )
-               printf("%s\n", path);
-
-       if ( !options.fFullyLoadArchives ) {
-               const Entry* const firstMember = (Entry*)&fFileContent[8];
-               if ( (strcmp(firstMember->getName(), SYMDEF_SORTED) == 0) || (strcmp(firstMember->getName(), SYMDEF) == 0) ) {
-                       const uint8_t* contents = firstMember->getContent();
-                       uint32_t ranlibArrayLen = E::get32(*((uint32_t*)contents));
-                       fTableOfContents = (const struct ranlib*)&contents[4];
-                       fTableOfContentCount = ranlibArrayLen / sizeof(struct ranlib);
-                       fStringPool = (const char*)&contents[ranlibArrayLen+8];
-                       if ( ((uint8_t*)(&fTableOfContents[fTableOfContentCount]) > &fileContent[fileLength])
-                               || ((uint8_t*)fStringPool > &fileContent[fileLength]) )
-                               throw "malformed archive, perhaps wrong architecture";
-                       this->buildHashTable();
-               }
-               else
-                       throw "archive has no table of contents";
-       }
-}
-
-
-template <typename A>
-ObjectFile::Reader* Reader<A>::makeObjectReaderForMember(const Entry* member)
-{
-       const char* memberName = member->getName();
-       char memberPath[strlen(fPath) + strlen(memberName)+4];
-       strcpy(memberPath, fPath);
-       strcat(memberPath, "(");
-       strcat(memberPath, memberName);
-       strcat(memberPath, ")");
-       //fprintf(stderr, "using %s from %s\n", memberName, fPath);
-       try {
-               // offset the ordinals in this mach-o .o file, so that atoms layout in same order as in archive
-               uint32_t ordinalBase =  fOrdinalBase + (uint8_t*)member - fFileContent;
-               return new typename mach_o::relocatable::Reader<A>::Reader(member->getContent(), memberPath, member->getModTime(), fOptions, ordinalBase);
-       }
-       catch (const char* msg) {
-               throwf("in %s, %s", memberPath, msg);
-       }
-}
-
-
-template <typename A>
-std::vector<class ObjectFile::Atom*>&  Reader<A>::getAtoms()
-{
-       if ( fOptions.fFullyLoadArchives ) {
-               // build vector of all atoms from all .o files in this archive
-               const Entry* const start = (Entry*)&fFileContent[8];
-               const Entry* const end = (Entry*)&fFileContent[fFileLength];
-               for (const Entry* p=start; p < end; p = p->getNext()) {
-                       const char* memberName = p->getName();
-                       if ( (p==start) && ((strcmp(memberName, SYMDEF_SORTED) == 0) || (strcmp(memberName, SYMDEF) == 0)) )
-                               continue;
-                       if ( fOptions.fWhyLoad )
-                               printf("-all_load forced load of %s(%s)\n", this->getPath(), memberName);
-                       ObjectFile::Reader* r = this->makeObjectReaderForMember(p);
-                       std::vector<class ObjectFile::Atom*>&   atoms = r->getAtoms();
-                       fAllAtoms.insert(fAllAtoms.end(), atoms.begin(), atoms.end());
-               }
-               return fAllAtoms;
-       }
-       else if ( fOptions.fLoadAllObjcObjectsFromArchives ) {
-               // build vector of all atoms from all .o files containing objc classes in this archive
-               for(class NameToEntryMap::iterator it = fHashTable.begin(); it != fHashTable.end(); ++it) {
-                       if ( (strncmp(it->first, ".objc_c", 7) == 0) || (strncmp(it->first, "_OBJC_CLASS_$_", 14) == 0) ) {
-                               const Entry* member = (Entry*)&fFileContent[E::get32(it->second->ran_off)];
-                               if ( fInstantiatedEntries.count(member) == 0 ) {
-                                       if ( fOptions.fWhyLoad )
-                                               printf("-ObjC forced load of %s(%s)\n", this->getPath(), member->getName());
-                                       // only return these atoms once
-                                       fInstantiatedEntries.insert(member);
-                                       ObjectFile::Reader* r = makeObjectReaderForMember(member);
-                                       std::vector<class ObjectFile::Atom*>&   atoms = r->getAtoms();
-                                       fAllAtoms.insert(fAllAtoms.end(), atoms.begin(), atoms.end());
-                               }
-                       }
-               }
-               return fAllAtoms;
-       }
-       else {
-               // return nonthing for now, getJustInTimeAtomsFor() will return atoms as needed
-               return fgEmptyList;
-       }
-}
-
-
-template <typename A>
-ConstRanLibPtr  Reader<A>::ranlibHashSearch(const char* name)
-{
-       class NameToEntryMap::iterator pos = fHashTable.find(name);
-       if ( pos != fHashTable.end() )
-               return pos->second;
-       else
-               return NULL;
-}
-
-template <typename A>
-void Reader<A>::buildHashTable()
-{
-       // walk through list backwards, adding/overwriting entries
-       // this assures that with duplicates those earliest in the list will be found
-       for (int i = fTableOfContentCount-1; i >= 0; --i) {
-               const struct ranlib* entry = &fTableOfContents[i];
-               const char* entryName = &fStringPool[E::get32(entry->ran_un.ran_strx)];
-               const Entry* member = (Entry*)&fFileContent[E::get32(entry->ran_off)];
-               //fprintf(stderr, "adding hash %d, %s -> %p\n", i, entryName, entry);
-               fHashTable[entryName] = entry;
-               fPossibleEntries.insert(member);
-       }
-}
-
-template <typename A>
-void Reader<A>::dumpTableOfContents()
-{
-       for (unsigned int i=0; i < fTableOfContentCount; ++i) {
-               const struct ranlib* e = &fTableOfContents[i];
-               printf("%s in %s\n", &fStringPool[E::get32(e->ran_un.ran_strx)], ((Entry*)&fFileContent[E::get32(e->ran_off)])->getName());
-       }
-}
-
-template <typename A>
-std::vector<class ObjectFile::Atom*>* Reader<A>::getJustInTimeAtomsFor(const char* name)
-{
-       if ( fOptions.fFullyLoadArchives ) {
-               return NULL;
-       }
-       else {
-               const struct ranlib* result = NULL;
-               // do a hash search of table of contents looking for requested symbol
-               result = ranlibHashSearch(name);
-               if ( result != NULL ) {
-                       const Entry* member = (Entry*)&fFileContent[E::get32(result->ran_off)];
-                       if ( fInstantiatedEntries.count(member) == 0 ) {
-                               if ( fOptions.fWhyLoad )
-                                       printf("%s forced load of %s(%s)\n", name, this->getPath(), member->getName());
-                               // only return these atoms once
-                               fInstantiatedEntries.insert(member);
-                               ObjectFile::Reader* r = makeObjectReaderForMember(member);
-                               return new std::vector<class ObjectFile::Atom*>(r->getAtoms());
-                       }
-               }
-               //fprintf(stderr, "%s NOT found in archive %s\n", name, fPath);
-               return NULL;
-       }
-}
-
-
-
-
-
-}; // namespace archive
-}; // namespace mach_o
-
-
-#endif // __OBJECT_FILE_ARCHIVE_MACH_O__
old mode 100644 (file)
new mode 100755 (executable)
index 28d019c..eb8e844
@@ -87,6 +87,7 @@ public:
        virtual SymbolTableInclusion                            getSymbolTableInclusion() const { return ObjectFile::Atom::kSymbolTableIn; }
        virtual bool                                                            dontDeadStrip() const           { return false; }
        virtual bool                                                            isZeroFill() const                      { return false; }
+       virtual bool                                                            isThumb() const                         { return false; }
        virtual uint64_t                                                        getSize() const                         { return 0; }
        virtual std::vector<ObjectFile::Reference*>&  getReferences() const             { return fgEmptyReferenceList; }
        virtual bool                                                            mustRemainInSection() const { return false; }
@@ -170,6 +171,7 @@ public:
        virtual SymbolTableInclusion                            getSymbolTableInclusion() const { return ObjectFile::Atom::kSymbolTableNotIn; }
        virtual bool                                                            dontDeadStrip() const           { return false; }
        virtual bool                                                            isZeroFill() const                      { return false; }
+       virtual bool                                                            isThumb() const                         { return false; }
        virtual uint64_t                                                        getSize() const                         { return 0; }
        virtual std::vector<ObjectFile::Reference*>&  getReferences() const             { return (std::vector<ObjectFile::Reference*>&)(fReferences); }
        virtual bool                                                            mustRemainInSection() const { return false; }
@@ -221,7 +223,7 @@ class Reader : public ObjectFile::Reader
 public:
        static bool                                                                             validFile(const uint8_t* fileContent, bool executableOrDylib);
                                                                                                        Reader(const uint8_t* fileContent, uint64_t fileLength, const char* path,
-                                                                                                               bool executableOrDylib, const ObjectFile::ReaderOptions& options,
+                                                                                                               const DynamicLibraryOptions& dylibOptions, const ObjectFile::ReaderOptions& options,
                                                                                                                uint32_t ordinalBase);
        virtual                                                                                 ~Reader() {}
 
@@ -243,6 +245,8 @@ public:
        virtual bool                                                                    providedExportAtom()            { return fProvidedAtom; }
        virtual const char*                                                             parentUmbrella()                        { return fParentUmbrella; }
        virtual std::vector<const char*>*                               getAllowableClients();
+       virtual bool                                                                    hasWeakExternals()                      { return fHasWeakExports; }
+       virtual bool                                                                    isLazyLoadedDylib()                     { return fLazyLoaded; }
 
        virtual void                                                                    setImplicitlyLinked()           { fImplicitlyLinked = true; }
 
@@ -250,7 +254,7 @@ protected:
 
        struct ReExportChain { ReExportChain* prev; Reader<A>* reader; };
 
-       void                                                                                    assertNoReExportCycles(std::set<ObjectFile::Reader*>& chainedReExportReaders, ReExportChain*);
+       void                                                                                    assertNoReExportCycles(ReExportChain*);
 
 private:
        typedef typename A::P                                           P;
@@ -283,12 +287,15 @@ private:
        NameToAtomMap                                                           fAtoms;
        NameSet                                                                         fIgnoreExports;
        bool                                                                            fNoRexports;
+       bool                                                                            fHasWeakExports;
        const bool                                                                      fLinkingFlat;
        const bool                                                                      fLinkingMainExecutable;
        bool                                                                            fExplictReExportFound;
        bool                                                                            fExplicitlyLinked;
        bool                                                                            fImplicitlyLinked;
        bool                                                                            fProvidedAtom;
+       bool                                                                            fImplicitlyLinkPublicDylibs;
+       bool                                                                            fLazyLoaded;
        ObjectFile::Reader::ObjcConstraint                      fObjcContraint;
        std::vector<ObjectFile::Reader*>                        fReExportedChildren;
        const ObjectFile::ReaderOptions::VersionMin     fDeploymentVersionMin;
@@ -305,16 +312,19 @@ bool                                                                      Reader<A>::fgLogHashtable = false;
 
 
 template <typename A>
-Reader<A>::Reader(const uint8_t* fileContent, uint64_t fileLength, const char* path, bool executableOrDylib, 
+Reader<A>::Reader(const uint8_t* fileContent, uint64_t fileLength, const char* path, 
+               const DynamicLibraryOptions& dylibOptions, 
                const ObjectFile::ReaderOptions& options, uint32_t ordinalBase)
        : fParentUmbrella(NULL), fDylibInstallPath(NULL), fDylibTimeStamp(0), fDylibtCurrentVersion(0), 
        fDylibCompatibilityVersion(0), fLinkingFlat(options.fFlatNamespace), 
        fLinkingMainExecutable(options.fLinkingMainExecutable), fExplictReExportFound(false), 
-       fExplicitlyLinked(false), fImplicitlyLinked(false), fProvidedAtom(false), fObjcContraint(ObjectFile::Reader::kObjcNone),
+       fExplicitlyLinked(false), fImplicitlyLinked(false), fProvidedAtom(false), 
+       fImplicitlyLinkPublicDylibs(options.fImplicitlyLinkPublicDylibs), fLazyLoaded(dylibOptions.fLazyLoad),
+       fObjcContraint(ObjectFile::Reader::kObjcNone),
        fDeploymentVersionMin(options.fVersionMin)
 {
        // sanity check
-       if ( ! validFile(fileContent, executableOrDylib) )
+       if ( ! validFile(fileContent, dylibOptions.fBundleLoader) )
                throw "not a valid mach-o object file";
 
        fPath = strdup(path);
@@ -322,16 +332,17 @@ Reader<A>::Reader(const uint8_t* fileContent, uint64_t fileLength, const char* p
        const macho_header<P>* header = (const macho_header<P>*)fileContent;
        const uint32_t cmd_count = header->ncmds();
        const macho_load_command<P>* const cmds = (macho_load_command<P>*)((char*)header + sizeof(macho_header<P>));
+       const macho_load_command<P>* const cmdsEnd = (macho_load_command<P>*)((char*)header + sizeof(macho_header<P>) + header->sizeofcmds());
 
        // write out path for -whatsloaded option
        if ( options.fLogAllFiles )
                printf("%s\n", path);
 
        if ( options.fRootSafe && ((header->flags() & MH_ROOT_SAFE) == 0) )
-               fprintf(stderr, "ld: warning using -root_safe but linking against %s which is not root safe\n", path);
+               warning("using -root_safe but linking against %s which is not root safe", path);
 
        if ( options.fSetuidSafe && ((header->flags() & MH_SETUID_SAFE) == 0) )
-               fprintf(stderr, "ld: warning using -setuid_safe but linking against %s which is not setuid safe\n", path);
+               warning("using -setuid_safe but linking against %s which is not setuid safe", path);
 
        // a "blank" stub has zero load commands
        if ( (header->filetype() == MH_DYLIB_STUB) && (cmd_count == 0) ) {      
@@ -343,6 +354,7 @@ Reader<A>::Reader(const uint8_t* fileContent, uint64_t fileLength, const char* p
 
        // optimize the case where we know there is no reason to look at indirect dylibs
        fNoRexports = (header->flags() & MH_NO_REEXPORTED_DYLIBS);
+       fHasWeakExports = (header->flags() & MH_WEAK_DEFINES);
        bool trackDependentLibraries = !fNoRexports || options.fFlatNamespace;
        
        // pass 1 builds list of all dependent libraries
@@ -362,6 +374,8 @@ Reader<A>::Reader(const uint8_t* fileContent, uint64_t fileLength, const char* p
                                        break;
                        }
                        cmd = (const macho_load_command<P>*)(((char*)cmd)+cmd->cmdsize());
+                       if ( cmd > cmdsEnd )
+                               throwf("malformed dylb, load command #%d is outside size of load commands in %s", i, path);
                }
        }
        
@@ -449,7 +463,7 @@ Reader<A>::Reader(const uint8_t* fileContent, uint64_t fileLength, const char* p
                                                                        fObjcContraint = ObjectFile::Reader::kObjcRetainRelease;
                                                        }
                                                        else if ( sect->size() > 0 ) {
-                                                               fprintf(stderr, "ld: warning, can't parse __OBJC/__image_info section in %s\n", fPath);
+                                                               warning("can't parse __OBJC/__image_info section in %s", fPath);
                                                        }
                                                }
                                        }
@@ -457,6 +471,8 @@ Reader<A>::Reader(const uint8_t* fileContent, uint64_t fileLength, const char* p
                }
 
                cmd = (const macho_load_command<P>*)(((char*)cmd)+cmd->cmdsize());
+               if ( cmd > cmdsEnd )
+                       throwf("malformed dylb, load command #%d is outside size of load commands in %s", i, path);
        }
        
        // Process the rest of the commands here.
@@ -472,12 +488,12 @@ Reader<A>::Reader(const uint8_t* fileContent, uint64_t fileLength, const char* p
        }
 
        // validate minimal load commands
-       if ( (fDylibInstallPath == NULL) && (header->filetype() != MH_EXECUTE) ) 
-               throw "dylib missing LC_ID_DYLIB load command";
+       if ( (fDylibInstallPath == NULL) && ((header->filetype() == MH_DYLIB) || (header->filetype() == MH_DYLIB_STUB)) ) 
+               throwf("dylib %s missing LC_ID_DYLIB load command", path);
        if ( symbolTable == NULL )
-               throw "dylib missing LC_SYMTAB load command";
+               throw "binary missing LC_SYMTAB load command";
        if ( dynamicInfo == NULL )
-               throw "dylib missing LC_DYSYMTAB load command";
+               throw "binary missing LC_DYSYMTAB load command";
        
        // if linking flat and this is a flat dylib, create one atom that references all imported symbols
        if ( fLinkingFlat && fLinkingMainExecutable && ((header->flags() & MH_TWOLEVEL) == 0) ) {
@@ -552,6 +568,9 @@ void Reader<A>::addSymbol(const char* name, bool weak, uint32_t ordinal)
                                        case 5:
                                                symVersionCondition = ObjectFile::ReaderOptions::k10_5;
                                                break;
+                                       case 6:
+                                               symVersionCondition = ObjectFile::ReaderOptions::k10_6;
+                                               break;
                                }
                                const char* symName = strchr(&symCond[1], '$');
                                if ( symName != NULL ) {
@@ -567,20 +586,20 @@ void Reader<A>::addSymbol(const char* name, bool weak, uint32_t ordinal)
                                                        return;
                                                }
                                                else {
-                                                       fprintf(stderr, "ld: warning bad symbol action: %s in dylib %s\n", name, this->getPath());
+                                                       warning("bad symbol action: %s in dylib %s", name, this->getPath());
                                                }
                                        }
                                }
                                else {
-                                       fprintf(stderr, "ld: warning bad symbol name: %s in dylib %s\n", name, this->getPath());
+                                       warning("bad symbol name: %s in dylib %s", name, this->getPath());
                                }
                        }
                        else {
-                               fprintf(stderr, "ld: warning bad symbol version: %s in dylib %s\n", name, this->getPath());
+                               warning("bad symbol version: %s in dylib %s", name, this->getPath());
                        }
                }       
                else {
-                       fprintf(stderr, "ld: warning bad symbol condition: %s in dylib %s\n", name, this->getPath());
+                       warning("bad symbol condition: %s in dylib %s", name, this->getPath());
                }
        }
        
@@ -650,6 +669,10 @@ std::vector<class ObjectFile::Atom*>* Reader<A>::getJustInTimeAtomsFor(const cha
 template <typename A>
 bool Reader<A>::isPublicLocation(const char* path)
 {
+       // -no_implicit_dylibs disables this optimization
+       if ( ! fImplicitlyLinkPublicDylibs )
+               return false;
+       
        // /usr/lib is a public location
        if ( (strncmp(path, "/usr/lib/", 9) == 0) && (strchr(&path[9], '/') == NULL) )
                return true;
@@ -723,30 +746,28 @@ void Reader<A>::processIndirectLibraries(DylibHander* handler)
        }
        
        // check for re-export cycles
-       std::set<ObjectFile::Reader*> chainedReExportReaders;
        ReExportChain chain;
        chain.prev = NULL;
        chain.reader = this;
-       this->assertNoReExportCycles(chainedReExportReaders, &chain);
+       this->assertNoReExportCycles(&chain);
 }
 
 template <typename A>
-void Reader<A>::assertNoReExportCycles(std::set<ObjectFile::Reader*>& chainedReExportReaders, ReExportChain* prev)
+void Reader<A>::assertNoReExportCycles(ReExportChain* prev)
 {
-       // check none of my re-exported dylibs are already in set
-       for (std::vector<ObjectFile::Reader*>::iterator it = fReExportedChildren.begin(); it != fReExportedChildren.end(); it++) {
-               if ( chainedReExportReaders.count(*it) != 0 ) {
-                       // we may want to print out the chain of dylibs causing the cylce...
-                       throwf("cycle in dylib re-exports with %s", this->getPath());
-               }
-       }
-       // recursively check my re-exportted dylibs
-       chainedReExportReaders.insert(this);
+       // recursively check my re-exported dylibs
        ReExportChain chain;
        chain.prev = prev;
        chain.reader = this;
        for (std::vector<ObjectFile::Reader*>::iterator it = fReExportedChildren.begin(); it != fReExportedChildren.end(); it++) {
-               ((Reader<A>*)(*it))->assertNoReExportCycles(chainedReExportReaders, &chain);
+               ObjectFile::Reader* child = *it;
+               // check child is not already in chain 
+               for (ReExportChain* p = prev; p != NULL; p = p->prev) {
+                       if ( p->reader == child ) {
+                               throwf("cycle in dylib re-exports with %s", child->getPath());
+                       }
+               }
+               ((Reader<A>*)(*it))->assertNoReExportCycles(&chain);
        }
 }
 
@@ -764,7 +785,7 @@ std::vector<const char*>* Reader<A>::getAllowableClients()
 }
 
 template <>
-bool Reader<ppc>::validFile(const uint8_t* fileContent, bool executableOrDylib)
+bool Reader<ppc>::validFile(const uint8_t* fileContent, bool executableOrDyliborBundle)
 {
        const macho_header<P>* header = (const macho_header<P>*)fileContent;
        if ( header->magic() != MH_MAGIC )
@@ -775,15 +796,23 @@ bool Reader<ppc>::validFile(const uint8_t* fileContent, bool executableOrDylib)
                case MH_DYLIB:
                case MH_DYLIB_STUB:
                        return true;
+               case MH_BUNDLE:
+                       if ( executableOrDyliborBundle )
+                               return true;
+                       else
+                               throw "can't link with bundle (MH_BUNDLE) only dylibs (MH_DYLIB)";
                case MH_EXECUTE:
-                       return executableOrDylib;
+                       if ( executableOrDyliborBundle )
+                               return true;
+                       else
+                               throw "can't link with a main executable";
                default:
                        return false;
        }
 }
 
 template <>
-bool Reader<ppc64>::validFile(const uint8_t* fileContent, bool executableOrDylib)
+bool Reader<ppc64>::validFile(const uint8_t* fileContent, bool executableOrDyliborBundle)
 {
        const macho_header<P>* header = (const macho_header<P>*)fileContent;
        if ( header->magic() != MH_MAGIC_64 )
@@ -794,15 +823,23 @@ bool Reader<ppc64>::validFile(const uint8_t* fileContent, bool executableOrDylib
                case MH_DYLIB:
                case MH_DYLIB_STUB:
                        return true;
+               case MH_BUNDLE:
+                       if ( executableOrDyliborBundle )
+                               return true;
+                       else
+                               throw "can't link with bundle (MH_BUNDLE) only dylibs (MH_DYLIB)";
                case MH_EXECUTE:
-                       return executableOrDylib;
+                       if ( executableOrDyliborBundle )
+                               return true;
+                       else
+                               throw "can't link with a main executable";
                default:
                        return false;
        }
 }
 
 template <>
-bool Reader<x86>::validFile(const uint8_t* fileContent, bool executableOrDylib)
+bool Reader<x86>::validFile(const uint8_t* fileContent, bool executableOrDyliborBundle)
 {
        const macho_header<P>* header = (const macho_header<P>*)fileContent;
        if ( header->magic() != MH_MAGIC )
@@ -813,15 +850,23 @@ bool Reader<x86>::validFile(const uint8_t* fileContent, bool executableOrDylib)
                case MH_DYLIB:
                case MH_DYLIB_STUB:
                        return true;
+               case MH_BUNDLE:
+                       if ( executableOrDyliborBundle )
+                               return true;
+                       else
+                               throw "can't link with bundle (MH_BUNDLE) only dylibs (MH_DYLIB)";
                case MH_EXECUTE:
-                       return executableOrDylib;
+                       if ( executableOrDyliborBundle )
+                               return true;
+                       else
+                               throw "can't link with a main executable";
                default:
                        return false;
        }
 }
 
 template <>
-bool Reader<x86_64>::validFile(const uint8_t* fileContent, bool executableOrDylib)
+bool Reader<x86_64>::validFile(const uint8_t* fileContent, bool executableOrDyliborBundle)
 {
        const macho_header<P>* header = (const macho_header<P>*)fileContent;
        if ( header->magic() != MH_MAGIC_64 )
@@ -832,15 +877,47 @@ bool Reader<x86_64>::validFile(const uint8_t* fileContent, bool executableOrDyli
                case MH_DYLIB:
                case MH_DYLIB_STUB:
                        return true;
+               case MH_BUNDLE:
+                       if ( executableOrDyliborBundle )
+                               return true;
+                       else
+                               throw "can't link with bundle (MH_BUNDLE) only dylibs (MH_DYLIB)";
                case MH_EXECUTE:
-                       return executableOrDylib;
+                       if ( executableOrDyliborBundle )
+                               return true;
+                       else
+                               throw "can't link with a main executable";
                default:
                        return false;
        }
 }
 
-
-
+template <>
+bool Reader<arm>::validFile(const uint8_t* fileContent, bool executableOrDyliborBundle)
+{
+       const macho_header<P>* header = (const macho_header<P>*)fileContent;
+       if ( header->magic() != MH_MAGIC )
+               return false;
+       if ( header->cputype() != CPU_TYPE_ARM )
+               return false;
+       switch ( header->filetype() ) {
+               case MH_DYLIB:
+               case MH_DYLIB_STUB:
+                       return true;
+               case MH_BUNDLE:
+                       if ( executableOrDyliborBundle )
+                               return true;
+                       else
+                               throw "can't link with bundle (MH_BUNDLE) only dylibs (MH_DYLIB)";
+               case MH_EXECUTE:
+                       if ( executableOrDyliborBundle )
+                               return true;
+                       else
+                               throw "can't link with a main executable";
+               default:
+                       return false;
+       }
+}
 
 }; // namespace dylib
 }; // namespace mach_o
old mode 100644 (file)
new mode 100755 (executable)
index 7f20ae3..466d5df
@@ -1,6 +1,6 @@
 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
  *
- * Copyright (c) 2005-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2005-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 #include <math.h>
 #include <unistd.h>
 #include <sys/param.h>
-#include <mach-o/ppc/reloc.h>
-#include <mach-o/stab.h>
-#include <mach-o/x86_64/reloc.h>
-#ifndef S_ATTR_DEBUG
- #define S_ATTR_DEBUG 0x02000000
-#endif
 
 #include <vector>
 #include <set>
@@ -60,6 +54,7 @@
 
 
 extern  __attribute__((noreturn)) void throwf(const char* format, ...);
+extern void warning(const char* format, ...);
 
 namespace mach_o {
 namespace relocatable {
@@ -143,7 +138,7 @@ Reference<A>::Reference(Kinds kind, const AtomAndOffset& at, const AtomAndOffset
        // - the reference type is only used with direct references
        // - the target is translation unit scoped
        // - the target kind is not regular (is weak or tentative)
-       if ( (kind != A::kNoFixUp) && (kind != A::kFollowOn) 
+       if ( (kind != A::kNoFixUp) && (kind != A::kFollowOn) && (kind != A::kGroupSubordinate)
                && (toTarget.atom->getScope() != ObjectFile::Atom::scopeTranslationUnit) 
                && (toTarget.atom->getDefinitionKind() != ObjectFile::Atom::kRegularDefinition) ) {
                fToTargetName = toTarget.atom->getName();
@@ -160,7 +155,7 @@ Reference<A>::Reference(Kinds kind, const AtomAndOffset& at, const AtomAndOffset
    fToTargetName(NULL), fFromTargetName(NULL), fKind(kind)
 {
        // make reference a by-name where needed
-       if ( (kind != A::kNoFixUp) && (kind != A::kFollowOn) 
+       if ( (kind != A::kNoFixUp) && (kind != A::kFollowOn) && (kind != A::kGroupSubordinate)
                && (toTarget.atom->getScope() != ObjectFile::Atom::scopeTranslationUnit)
                && (toTarget.atom->getDefinitionKind() != ObjectFile::Atom::kRegularDefinition) 
                && (toTarget.atom != at.atom) ) {
@@ -343,7 +338,7 @@ public:
                                        default:
                                                // hack for rdar://problem/5102873
                                                if ( !left->isZeroFill() || !right->isZeroFill() )
-                                                       fprintf(stderr, "ld: atom sorting error for %s and %s in %s\n", left->getDisplayName(), right->getDisplayName(), left->getFile()->getPath());
+                                                       warning("atom sorting error for %s and %s in %s", left->getDisplayName(), right->getDisplayName(), left->getFile()->getPath());
                                                break;
                                }
                        }
@@ -373,6 +368,7 @@ public:
        virtual SymbolTableInclusion                            getSymbolTableInclusion() const { return fSymbolTableInclusion; }
        virtual bool                                                            dontDeadStrip() const;
        virtual bool                                                            isZeroFill() const                              { return ((fSection->flags() & SECTION_TYPE) == S_ZEROFILL); }
+       virtual bool                                                            isThumb() const                                 { return ((fSymbol->n_desc() & N_ARM_THUMB_DEF) != 0); }
        virtual uint64_t                                                        getSize() const                                 { return fSize; }
        virtual std::vector<ObjectFile::Reference*>&  getReferences() const                     { return (std::vector<ObjectFile::Reference*>&)(fReferences); }
        virtual bool                                                            mustRemainInSection() const             { return true; }
@@ -432,10 +428,18 @@ SymbolAtom<A>::SymbolAtom(Reader<A>& owner, const macho_nlist<P>* symbol, const
                // real definition
                fSegment = new Segment<A>(fSection);
                fAddress = fSymbol->n_value();
+               pint_t sectionStartAddr = section->addr();
+               pint_t sectionEndAddr = section->addr()+section->size();
+               if ( (fAddress < sectionStartAddr) || (fAddress > (sectionEndAddr)) ) {
+                       throwf("malformed .o file, symbol %s with address 0x%0llX is not with section %d (%s,%s) address range of 0x%0llX to 0x%0llX",
+                               this->getName(), (uint64_t)fAddress, fSymbol->n_sect(), section->segname(), section->sectname(), 
+                               (uint64_t)sectionStartAddr, (uint64_t)(sectionEndAddr) );
+               }
        }       
        else {
-               printf("unknown symbol type: %d\n", type);
+               warning("unknown symbol type: %d", type);
        }
+       
        //fprintf(stderr, "SymbolAtom(%p) %s fAddress=0x%X\n", this, this->getDisplayName(), (uint32_t)fAddress);
        // support for .o files built with old ld64
        if ( (fSymbol->n_desc() & N_WEAK_DEF) && (strcmp(fSection->sectname(),"__picsymbolstub1__TEXT") == 0) ) {
@@ -611,6 +615,7 @@ public:
        virtual SymbolTableInclusion                            getSymbolTableInclusion() const { return fAliasOf.getSymbolTableInclusion(); }
        virtual bool                                                            dontDeadStrip() const                   { return fDontDeadStrip; }
        virtual bool                                                            isZeroFill() const                              { return fAliasOf.isZeroFill(); }
+       virtual bool                                                            isThumb() const                                 { return fAliasOf.isThumb(); }
        virtual uint64_t                                                        getSize() const                                 { return 0; }
        virtual std::vector<ObjectFile::Reference*>&  getReferences() const                     { return (std::vector<ObjectFile::Reference*>&)(fReferences); }
        virtual bool                                                            mustRemainInSection() const             { return true; }
@@ -689,6 +694,7 @@ public:
        virtual ObjectFile::Atom::Scope                         getScope() const                                { return fScope; }
        virtual ObjectFile::Atom::DefinitionKind        getDefinitionKind() const               { return ObjectFile::Atom::kTentativeDefinition; }
        virtual bool                                                            isZeroFill() const                              { return true; }
+       virtual bool                                                            isThumb() const                                 { return false; }
        virtual SymbolTableInclusion                            getSymbolTableInclusion() const { return ((fSymbol->n_desc() & REFERENCED_DYNAMICALLY) != 0)
                                                                                                                                                                                ? ObjectFile::Atom::kSymbolTableInAndNeverStrip : ObjectFile::Atom::kSymbolTableIn; }
        virtual bool                                                            dontDeadStrip() const                   { return ((fSymbol->n_desc() & (N_NO_DEAD_STRIP|REFERENCED_DYNAMICALLY)) != 0); }
@@ -743,7 +749,7 @@ TentativeAtom<A>::TentativeAtom(Reader<A>& owner, const macho_nlist<P>* symbol)
                // tentative definition
        }
        else {
-               printf("unknown symbol type: %d\n", type);
+               warning("unknown symbol type: %d", type);
        }
        //fprintf(stderr, "TentativeAtom(%p) %s\n", this, this->getDisplayName());
 }
@@ -801,10 +807,11 @@ public:
        virtual const char*                                                     getName() const                                 { return fSynthesizedName; }
        virtual const char*                                                     getDisplayName() const;
        virtual ObjectFile::Atom::Scope                         getScope() const;
-       virtual ObjectFile::Atom::DefinitionKind        getDefinitionKind() const;
+       virtual ObjectFile::Atom::DefinitionKind        getDefinitionKind() const       { return fKind; }
        virtual ObjectFile::Atom::SymbolTableInclusion getSymbolTableInclusion() const  { return fSymbolTableInclusion; }
        virtual bool                                                            dontDeadStrip() const                   { return fDontDeadStrip; }
        virtual bool                                                            isZeroFill() const;
+       virtual bool                                                            isThumb() const                                 { return false; }
        virtual uint64_t                                                        getSize() const                                 { return fSize; }
        virtual std::vector<ObjectFile::Reference*>&  getReferences() const                     { return (std::vector<ObjectFile::Reference*>&)(fReferences); }
        virtual bool                                                            mustRemainInSection() const             { return true; }
@@ -818,7 +825,7 @@ public:
        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) { fprintf(stderr, "ld: can't add line info to anonymous symbol %s from %s\n", this->getDisplayName(), this->getFile()->getPath()); }
+       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 uint64_t                                                        getObjectAddress() const                { return fAddress; }
        virtual const void*                                                     getSectionRecord() const                { return (const void*)fSection; }
        BaseAtom*                                                                       redirectTo()                                    { return fRedirect; }
@@ -835,7 +842,7 @@ protected:
        typedef typename ReferenceVector::const_iterator        ReferenceVectorConstIterator;   // seems to help C++ parser
        friend class Reader<A>;
 
-                                                                                       AnonymousAtom(Reader<A>&, const macho_section<P>*, uint32_t addr, uint32_t size);
+                                                                                       AnonymousAtom(Reader<A>&, const macho_section<P>*, pint_t addr, pint_t size);
        virtual                                                                 ~AnonymousAtom() {}
        static bool                                                                     cstringsHaveLabels();
 
@@ -843,8 +850,8 @@ protected:
        const char*                                                                     fSynthesizedName;
        const char*                                                                     fDisplayName;
        const macho_section<P>*                                         fSection;
-       uint32_t                                                                        fAddress;
-       uint32_t                                                                        fSize;
+       pint_t                                                                          fAddress;
+       pint_t                                                                          fSize;
        Segment<A>*                                                                     fSegment;
        ReferenceVector                                                         fReferences;
        BaseAtom*                                                                       fRedirect;
@@ -852,18 +859,19 @@ protected:
        bool                                                                            fWeakImportStub;
        ObjectFile::Atom::SymbolTableInclusion          fSymbolTableInclusion;
        ObjectFile::Atom::Scope                                         fScope;
+    ObjectFile::Atom::DefinitionKind            fKind;
 };
 
 template <typename A>
-AnonymousAtom<A>::AnonymousAtom(Reader<A>& owner, const macho_section<P>* section, uint32_t addr, uint32_t size)
+AnonymousAtom<A>::AnonymousAtom(Reader<A>& owner, const macho_section<P>* section, pint_t addr, pint_t size)
  : fOwner(owner), fSynthesizedName(NULL), fDisplayName(NULL), fSection(section), fAddress(addr), fSize(size), 
        fSegment(NULL), fDontDeadStrip(true), fWeakImportStub(false), fSymbolTableInclusion(ObjectFile::Atom::kSymbolTableNotIn),
-       fScope(ObjectFile::Atom::scopeTranslationUnit)
+       fScope(ObjectFile::Atom::scopeTranslationUnit), fKind(ObjectFile::Atom::kRegularDefinition)
 {
        fSegment = new Segment<A>(fSection);
        fRedirect = this;
        uint8_t type = fSection->flags() & SECTION_TYPE;
-       //fprintf(stderr, "AnonymousAtom(%p) addr=0x%X in %s from %s\n", this, addr, section->sectname(), owner.getPath());
+       //fprintf(stderr, "AnonymousAtom(%p) addr=0x%llX in %s from %s\n", this, (long long)addr, section->sectname(), owner.getPath());
        switch ( type ) {
                case S_ZEROFILL:
                        {
@@ -888,12 +896,21 @@ AnonymousAtom<A>::AnonymousAtom(Reader<A>& owner, const macho_section<P>* sectio
                                const char* str = (char*)(owner.fHeader) + section->offset() + addr - section->addr();
                                asprintf((char**)&fSynthesizedName, "cstring=%s", str);
                        }
+                       else if ((strcmp(section->sectname(), "__cfstring") == 0) && (strcmp(section->segname(), "__DATA") == 0)) {
+                               fSynthesizedName = "cfstring-pointer-name-PENDING";
+                               fScope = ObjectFile::Atom::scopeLinkageUnit;
+                               owner.fAtomsPendingAName.push_back(this);
+                               owner.fSectionsWithAtomsPendingAName.insert(fSection);
+                               fDontDeadStrip = false;
+                               fKind = ObjectFile::Atom::kWeakDefinition;
+                       }
                        break;
                case S_CSTRING_LITERALS:
                        {
                                const char* str = (char*)(owner.fHeader) + section->offset() + addr - section->addr();
                                asprintf((char**)&fSynthesizedName, "cstring=%s", str);
                                fScope = ObjectFile::Atom::scopeLinkageUnit;
+                               fKind = ObjectFile::Atom::kWeakDefinition;
                                fDontDeadStrip = false;
                                if ( !fOwner.fOptions.fForFinalLinkedImage && cstringsHaveLabels() ) 
                                        fSymbolTableInclusion = ObjectFile::Atom::kSymbolTableIn;
@@ -904,6 +921,7 @@ AnonymousAtom<A>::AnonymousAtom(Reader<A>& owner, const macho_section<P>* sectio
                                uint32_t value =  E::get32(*(uint32_t*)(((uint8_t*)owner.fHeader) + section->offset() + addr - section->addr()));
                                asprintf((char**)&fSynthesizedName, "4-byte-literal=0x%08X", value);
                                fScope = ObjectFile::Atom::scopeLinkageUnit;
+                               fKind = ObjectFile::Atom::kWeakDefinition;
                                fDontDeadStrip = false;
                        }
                        break;
@@ -912,6 +930,7 @@ AnonymousAtom<A>::AnonymousAtom(Reader<A>& owner, const macho_section<P>* sectio
                                uint64_t value =  E::get64(*(uint64_t*)(((uint8_t*)owner.fHeader) + section->offset() + addr - section->addr()));
                                asprintf((char**)&fSynthesizedName, "8-byte-literal=0x%016llX", value);
                                fScope = ObjectFile::Atom::scopeLinkageUnit;
+                               fKind = ObjectFile::Atom::kWeakDefinition;
                                fDontDeadStrip = false;
                        }
                        break;
@@ -921,6 +940,7 @@ AnonymousAtom<A>::AnonymousAtom(Reader<A>& owner, const macho_section<P>* sectio
                                uint64_t value2 =  E::get64(*(uint64_t*)(((uint8_t*)owner.fHeader) + section->offset() + addr + 8 - section->addr()));
                                asprintf((char**)&fSynthesizedName, "16-byte-literal=0x%016llX,%016llX", value1, value2);
                                fScope = ObjectFile::Atom::scopeLinkageUnit;
+                               fKind = ObjectFile::Atom::kWeakDefinition;
                                fDontDeadStrip = false;
                        }
                        break;
@@ -931,6 +951,8 @@ AnonymousAtom<A>::AnonymousAtom(Reader<A>& owner, const macho_section<P>* sectio
                                //asprintf((char**)&fSynthesizedName, "literal-pointer@%s@%s@%s", section->segname(), section->sectname(), str);
                                fSynthesizedName = "literal-pointer-name-PENDING";
                                fScope = ObjectFile::Atom::scopeLinkageUnit;
+                               fKind = ObjectFile::Atom::kWeakDefinition;
+                               fDontDeadStrip = false;
                                owner.fAtomsPendingAName.push_back(this);
                                owner.fSectionsWithAtomsPendingAName.insert(fSection);
                        }
@@ -959,6 +981,7 @@ AnonymousAtom<A>::AnonymousAtom(Reader<A>& owner, const macho_section<P>* sectio
                                        if ( staticAtom != NULL ) 
                                                fRedirect = staticAtom;
                                }
+                               fKind = ObjectFile::Atom::kWeakDefinition;
                                // might be a spurious stub for a static function, make stub static too
                                if ( (sym->n_type() & N_EXT) == 0 ) 
                                        fScope = ObjectFile::Atom::scopeTranslationUnit;
@@ -1024,14 +1047,18 @@ AnonymousAtom<A>::AnonymousAtom(Reader<A>& owner, const macho_section<P>* sectio
                                        strcat(str, "$non_lazy_ptr");
                                fSynthesizedName = str;
 
-                               // optimize __IMPORT segment out of i386 dyld
-                               if ( fOwner.fOptions.fForDyld  && (strcmp(fSection->segname(),"__IMPORT") == 0) ) {
+                               // optimize __IMPORT segment out of i386 dyld or if -slow_stubs is used
+                               if ( (fOwner.fOptions.fForDyld || fOwner.fOptions.fSlowx86Stubs) && (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());
@@ -1084,12 +1111,37 @@ void AnonymousAtom<A>::resolveName()
                }
        }
        else if ( (fSection->flags() & SECTION_TYPE) == S_LITERAL_POINTERS) {
-               ObjectFile::Reference* ref = this->getReferences()[0];
+               std::vector<ObjectFile::Reference*>&  references = this->getReferences();
+               if ( references.size() < 1 )
+                       throwf("S_LITERAL_POINTERS section %s,%s missing relocs", fSection->segname(), fSection->sectname());
+               ObjectFile::Reference* ref = references[0];
                const char* str = ref->getTargetName();
                if ( strncmp(str, "cstring=", 8) == 0 ) {
                        asprintf((char**)&fSynthesizedName, "literal-pointer@%s@%s@%s", fSection->segname(), fSection->sectname(), &str[8]);
                }
        }
+       else if ( (strcmp(fSection->sectname(), "__cfstring") == 0) && (strcmp(fSection->segname(), "__DATA") == 0) ) {
+               // references are not yet sorted, so scan the vector
+               std::vector<ObjectFile::Reference*>&  references = this->getReferences();
+               for (std::vector<ObjectFile::Reference*>::iterator rit=references.begin(); rit != references.end(); rit++) {
+                       if ( ((*rit)->getFixUpOffset() == 2*sizeof(pint_t)) && ((*rit)->getKind() == A::kPointer) ) {
+                               const char* superStr = (*rit)->getTargetName();
+                               if ( (superStr != NULL) && (strncmp(superStr, "cstring=", 8) == 0) ) {
+                                       asprintf((char**)&fSynthesizedName, "cfstring=%s", &superStr[8]);
+                               }
+                               else {
+                                       // compiled with -fwritable-strings or a non-ASCII string 
+                                       ObjectFile::Atom& stringDataAtom = (*rit)->getTarget();
+                                       uint8_t buffer[stringDataAtom.getSize()];
+                                       stringDataAtom.copyRawContent(buffer);
+                                       fKind = ObjectFile::Atom::kRegularDefinition; // these are not coalescable
+                                       fScope = ObjectFile::Atom::scopeTranslationUnit;
+                                       fSynthesizedName = "cfstring-not-coalesable";
+                               }
+                               break;
+                       }
+               }
+       }
 }
 
 
@@ -1119,27 +1171,6 @@ ObjectFile::Atom::Scope AnonymousAtom<A>::getScope() const
        return fScope;
 }
 
-template <typename A>
-ObjectFile::Atom::DefinitionKind AnonymousAtom<A>::getDefinitionKind() const
-{
-       // in order for literals to be coalesced they must be weak
-       switch ( fSection->flags() & SECTION_TYPE ) {
-               case S_CSTRING_LITERALS:
-               case S_4BYTE_LITERALS:
-               case S_8BYTE_LITERALS:
-               case S_16BYTE_LITERALS:
-               case S_SYMBOL_STUBS:
-               case S_LITERAL_POINTERS:
-                       return ObjectFile::Atom::kWeakDefinition;
-               case S_NON_LAZY_SYMBOL_POINTERS:
-                       if ( fScope == ObjectFile::Atom::scopeTranslationUnit )
-                               return ObjectFile::Atom::kRegularDefinition;
-                       else
-                               return ObjectFile::Atom::kWeakDefinition;
-               default:
-                       return ObjectFile::Atom::kRegularDefinition;
-       }
-}
 
 template <typename A>
 bool AnonymousAtom<A>::isZeroFill() const
@@ -1221,6 +1252,7 @@ public:
        virtual ObjectFile::Atom::Scope                         getScope() const                                { return fScope; }
        virtual ObjectFile::Atom::DefinitionKind        getDefinitionKind() const               { return ObjectFile::Atom::kAbsoluteSymbol; }
        virtual bool                                                            isZeroFill() const                              { return false; }
+       virtual bool                                                            isThumb() const                                 { return ((fSymbol->n_desc() & N_ARM_THUMB_DEF) != 0); }
        virtual SymbolTableInclusion                            getSymbolTableInclusion() const { return ObjectFile::Atom::kSymbolTableInAsAbsolute; }
        virtual bool                                                            dontDeadStrip() const                   { return false; }
        virtual uint64_t                                                        getSize() const                                 { return 0; }
@@ -1295,9 +1327,10 @@ public:
        virtual std::vector<class ObjectFile::Atom*>*   getJustInTimeAtomsFor(const char* name) { return NULL; }
        virtual std::vector<Stab>*                                              getStabs()                              { return &fStabs; }
        virtual ObjectFile::Reader::ObjcConstraint              getObjCConstraint()             { return fObjConstraint; }
-       virtual ObjectFile::Reader::CpuConstraint               getCpuConstraint()              { return fCpuConstraint; }
+    virtual uint32_t                                updateCpuConstraint(uint32_t current);
        virtual bool                                                                    canScatterAtoms()               { return (fHeader->flags() & MH_SUBSECTIONS_VIA_SYMBOLS); }
        virtual bool                                                                    objcReplacementClasses(){ return fReplacementClasses; }
+       virtual bool                                                                    hasLongBranchStubs()    { return fHasLongBranchStubs; }
 
         bool                                                                                   getTranslationUnitSource(const char** dir, const char** name) const;
 
@@ -1312,24 +1345,24 @@ private:
        friend class TentativeAtom<A>;
        friend class AbsoluteAtom<A>;
        friend class SymbolAtom<A>;
+       typedef std::map<pint_t, BaseAtom*>                     AddrToAtomMap;
 
        void                                                                            addReferencesForSection(const macho_section<P>* sect);
        bool                                                                            addRelocReference(const macho_section<P>* sect, const macho_relocation_info<P>* reloc);
        bool                                                                            addRelocReference_powerpc(const macho_section<P>* sect, const macho_relocation_info<P>* reloc);
-       Kinds                                                                           pointerDiffKindForLength_powerpc(uint8_t r_length);
        bool                                                                            read_comp_unit(const char ** name, const char ** comp_dir, uint64_t *stmt_list);
        static bool                                                                     isWeakImportSymbol(const macho_nlist<P>* sym);
        static bool                                                                     skip_form(const uint8_t ** offset, const uint8_t * end, uint64_t form, uint8_t addr_size, bool dwarf64);
        static const char*                                                      assureFullPath(const char* path);
-       AtomAndOffset                                                           findAtomAndOffset(uint32_t addr);
-       AtomAndOffset                                                           findAtomAndOffset(uint32_t baseAddr, uint32_t realAddr);
-       Reference<A>*                                                           makeReference(Kinds kind, uint32_t atAddr, uint32_t toAddr);
-       Reference<A>*                                                           makeReference(Kinds kind, uint32_t atAddr, uint32_t fromAddr, uint32_t toAddr);
-       Reference<A>*                                                           makeReferenceWithToBase(Kinds kind, uint32_t atAddr, uint32_t toAddr, uint32_t toBaseAddr);
-       Reference<A>*                                                           makeReferenceWithToBase(Kinds kind, uint32_t atAddr, uint32_t fromAddr, uint32_t toAddr, uint32_t toBaseAddr);
-       Reference<A>*                                                           makeByNameReference(Kinds kind, uint32_t atAddr, const char* toName, uint32_t toOffset);
+       AtomAndOffset                                                           findAtomAndOffset(pint_t addr);
+       AtomAndOffset                                                           findAtomAndOffset(pint_t baseAddr, pint_t realAddr);
+       Reference<A>*                                                           makeReference(Kinds kind, pint_t atAddr, pint_t toAddr);
+       Reference<A>*                                                           makeReference(Kinds kind, pint_t atAddr, pint_t fromAddr, pint_t toAddr);
+       Reference<A>*                                                           makeReferenceWithToBase(Kinds kind, pint_t atAddr, pint_t toAddr, pint_t toBaseAddr);
+       Reference<A>*                                                           makeReferenceWithToBase(Kinds kind, pint_t atAddr, pint_t fromAddr, pint_t toAddr, pint_t toBaseAddr);
+       Reference<A>*                                                           makeByNameReference(Kinds kind, pint_t atAddr, const char* toName, uint32_t toOffset);
        Reference<A>*                                                           makeReferenceToEH(const char* ehName, pint_t ehAtomAddress, const macho_section<P>* ehSect);
-       Reference<A>*                                                           makeReferenceToSymbol(Kinds kind, uint32_t atAddr, const macho_nlist<P>* toSymbol, uint32_t toOffset);
+       Reference<A>*                                                           makeReferenceToSymbol(Kinds kind, pint_t atAddr, const macho_nlist<P>* toSymbol, pint_t toOffset);
        void                                                                            validSectionType(uint8_t type);
        void                                                                            addDtraceExtraInfos(uint32_t probeAddr, const char* providerName);
        void                                                                            setCpuConstraint(uint32_t cpusubtype);
@@ -1347,8 +1380,8 @@ private:
        const macho_segment_command<P>*                         fSegment;
        const uint32_t*                                                         fIndirectTable;
        std::vector<BaseAtom*>                                          fAtoms;
-       std::map<uint32_t, BaseAtom*>                           fAddrToAtom;
-       std::map<uint32_t, BaseAtom*>                           fAddrToAbsoluteAtom;
+       AddrToAtomMap                                                           fAddrToAtom;
+       AddrToAtomMap                                                           fAddrToAbsoluteAtom;
        std::vector<class AnonymousAtom<A>*>            fLocalNonLazys;
        std::vector<class AnonymousAtom<A>*>            fAtomsPendingAName;
        std::set<const macho_section<P>*>                       fSectionsWithAtomsPendingAName;
@@ -1366,8 +1399,9 @@ private:
        bool                                                                            fHasDTraceProbes;
        bool                                                                            fHaveIndirectSymbols;
        bool                                                                            fReplacementClasses;
+       bool                                                                            fHasLongBranchStubs;
        ObjectFile::Reader::ObjcConstraint                      fObjConstraint;
-       ObjectFile::Reader::CpuConstraint                       fCpuConstraint;
+       uint32_t                                    fCpuConstraint;
 };
 
 template <typename A>
@@ -1376,7 +1410,7 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
         fStrings(NULL), fSymbols(NULL), fSymbolCount(0), fSegment(NULL), fIndirectTable(NULL),
         fDebugInfo(kDebugInfoNone), fHasUUID(false), fDwarfDebugInfoSect(NULL), fDwarfDebugAbbrevSect(NULL), fDwarfDebugLineSect(NULL),
          fDwarfTranslationUnitDir(NULL), fDwarfTranslationUnitFile(NULL), fAppleObjc(false), fHasDTraceProbes(false),
-         fHaveIndirectSymbols(false), fReplacementClasses(false), 
+         fHaveIndirectSymbols(false), fReplacementClasses(false), fHasLongBranchStubs(false),
          fObjConstraint(ObjectFile::Reader::kObjcNone), fCpuConstraint(ObjectFile::Reader::kCpuAny) 
 {
        // sanity check
@@ -1394,6 +1428,7 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
        this->setCpuConstraint(header->cpusubtype());
        const uint32_t cmd_count = header->ncmds();
        const macho_load_command<P>* const cmds = (macho_load_command<P>*)((char*)header + sizeof(macho_header<P>));
+       const macho_load_command<P>* const cmdsEnd = (macho_load_command<P>*)((char*)header + sizeof(macho_header<P>) + header->sizeofcmds());
        const macho_load_command<P>* cmd = cmds;
        uint32_t undefinedStartIndex = 0;
        uint32_t undefinedEndIndex = 0;
@@ -1430,7 +1465,14 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                                break;
                }
                cmd = (const macho_load_command<P>*)(((char*)cmd)+cmd->cmdsize());
+               if ( cmd > cmdsEnd )
+                       throwf("malformed dylb, load command #%d is outside size of load commands in %s", i, path);
        }
+
+       // if there are no load commands, then this file has no content, so no atoms
+       if ( header->ncmds() < 1 )
+               return;
+
        const macho_section<P>* const sectionsStart = (macho_section<P>*)((char*)fSegment + sizeof(macho_segment_command<P>));
        const macho_section<P>* const sectionsEnd = &sectionsStart[fSegment->nsects()];
 
@@ -1471,7 +1513,7 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                                                        case S_CSTRING_LITERALS:
                                                                {
                                                                        BaseAtom* newAtom;
-                                                                       std::map<uint32_t, BaseAtom*>::iterator pos = fAddrToAtom.find(sym.n_value());
+                                                                       typename AddrToAtomMap::iterator pos = fAddrToAtom.find(sym.n_value());
                                                                        if ( (pos != fAddrToAtom.end()) && (strcmp(pos->second->getSectionName(), section->sectname())==0) ) {
                                                                                // another label to an existing address in the same section, make this an alias
                                                                                newAtom = new SymbolAliasAtom<A>(&fStrings[sym.n_strx()], &sym, *pos->second);
@@ -1481,7 +1523,7 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                                                                                newAtom = new SymbolAtom<A>(*this, &sym, section);
                                                                                // don't add symbols at end of section to addr->atom map
                                                                                if ( sym.n_value() != sectionEndAddr )
-                                                                                       fAddrToAtom[sym.n_value()] = newAtom;
+                                                                                       fAddrToAtom[newAtom->getObjectAddress()] = newAtom;
                                                                        }
                                                                        if ( ! suppress )
                                                                                fAtoms.push_back(newAtom);
@@ -1493,7 +1535,7 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                                                                // ignore symboled stubs produces by old ld64
                                                                break;
                                                        default:
-                                                               fprintf(stderr, "ld: warning symbol %s found in unsupported section in %s\n",
+                                                               warning("symbol %s found in unsupported section in %s",
                                                                        &fStrings[sym.n_strx()], this->getPath());
                                                }
                                        }
@@ -1504,7 +1546,7 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                        }
                        else if ( type == N_ABS ) {
                                const char* symName = &fStrings[sym.n_strx()];
-                               if ( strncmp(symName, ".objc_class_name_", 16) == 0 ) {
+                               if ( strncmp(symName, ".objc_class_name_", 17) == 0 ) {
                                        // ignore .objc_class_name_* symbols 
                                        fAppleObjc = true;
                                }
@@ -1525,7 +1567,7 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
 
        // add all fixed size anonymous atoms from special sections
        for (const macho_section<P>* sect=sectionsStart; sect < sectionsEnd; ++sect) {
-               uint32_t atomSize = 0;
+               pint_t atomSize = 0;
                uint8_t type (sect->flags() & SECTION_TYPE);
                validSectionType(type);
                bool suppress = false;
@@ -1589,14 +1631,18 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                                                suppress = true;
                                        }
                                        else {
-                                               fprintf(stderr, "can't parse __OBJC/__image_info section in %s\n", fPath);
+                                               warning("can't parse __OBJC/__image_info section in %s", fPath);
                                        }
                                }
+                               // special case constant NS/CFString literals and make an atom out of each one
+                               else if ((strcmp(sect->sectname(), "__cfstring") == 0) && (strcmp(sect->segname(), "__DATA") == 0)) {
+                                       atomSize = 4 * sizeof(pint_t);
+                               }
                                break;
                }
                if ( atomSize != 0 ) {
-                       for(uint32_t sectOffset=0; sectOffset < sect->size(); sectOffset += atomSize) {
-                               uint32_t atomAddr = sect->addr() + sectOffset;
+                       for(pint_t sectOffset=0; sectOffset < sect->size(); sectOffset += atomSize) {
+                               pint_t atomAddr = sect->addr() + sectOffset;
                                // add if not already an atom at that address
                                if ( fAddrToAtom.find(atomAddr) == fAddrToAtom.end() ) {
                                        AnonymousAtom<A>* newAtom = new AnonymousAtom<A>(*this, sect, atomAddr, atomSize);
@@ -1612,11 +1658,11 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
        for (const macho_section<P>* sect=sectionsStart; sect < sectionsEnd; ++sect) {
                if ( ((sect->flags() & SECTION_TYPE) == S_CSTRING_LITERALS) || strcmp(sect->sectname(), "__cstring") == 0 ) {
                        uint32_t stringLen;
-                       uint32_t stringAddr;
+                       pint_t stringAddr;
                        BaseAtom* mostAlignedEmptyString = NULL;
                        uint32_t mostAlignedEmptyStringTrailingZeros = 0;
-                       std::vector<std::pair<uint32_t,BaseAtom*> > emptyStrings;
-                       for(uint32_t sectOffset=0; sectOffset < sect->size(); sectOffset += stringLen) {
+                       std::vector<std::pair<pint_t,BaseAtom*> > emptyStrings;
+                       for(pint_t sectOffset=0; sectOffset < sect->size(); sectOffset += stringLen) {
                                stringAddr = sect->addr() + sectOffset;
                                stringLen  = strlen((char*)(fHeader) + sect->offset() + sectOffset) + 1;
                                // add if not already an atom at that address
@@ -1624,7 +1670,7 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                                        BaseAtom* newAtom = new AnonymousAtom<A>(*this, sect, stringAddr, stringLen);
                                        if ( stringLen == 1 ) {
                                                // because of padding it may look like there are lots of empty strings, keep track of all
-                                               emptyStrings.push_back(std::make_pair<uint32_t,BaseAtom*>(stringAddr, newAtom));
+                                               emptyStrings.push_back(std::make_pair<pint_t,BaseAtom*>(stringAddr, newAtom));
                                                // record empty string with greatest alignment requirement
                                                uint32_t stringAddrTrailingZeros = (stringAddr==0) ? sect->align() : __builtin_ctz(stringAddr);
                                                if ( (mostAlignedEmptyString == NULL) 
@@ -1644,7 +1690,7 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                                // make most aligned atom a real atom
                                fAtoms.push_back(mostAlignedEmptyString);
                                // map all other empty atoms to this one
-                               for (std::vector<std::pair<uint32_t,BaseAtom*> >::iterator it=emptyStrings.begin(); it != emptyStrings.end(); it++) {
+                               for (typename std::vector<std::pair<pint_t,BaseAtom*> >::iterator it=emptyStrings.begin(); it != emptyStrings.end(); it++) {
                                        fAddrToAtom[it->first] = mostAlignedEmptyString;
                                }
                        }
@@ -1684,7 +1730,7 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                                        case S_ZEROFILL:
                                        case S_COALESCED:
                                                // if there is not an atom already at the start of this section, add an anonymous one
-                                               uint32_t previousAtomAddr = 0;
+                                               pint_t previousAtomAddr = 0;
                                                BaseAtom* previousAtom = NULL;
                                                if ( fAddrToAtom.find(sectionStartAddr) == fAddrToAtom.end() ) {
                                                        BaseAtom* newAtom = new AnonymousAtom<A>(*this, sect, sect->addr(), 0);
@@ -1697,9 +1743,9 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                                                // calculate size of all atoms in this section and add follow-on references
                                                for (std::vector<BaseAtom*>::iterator it=fAtoms.begin(); it != fAtoms.end(); it++) {
                                                        BaseAtom* atom = (BaseAtom*)(*it);
-                                                       uint32_t atomAddr = atom->getObjectAddress();
+                                                       pint_t atomAddr = atom->getObjectAddress();
                                                        if ( atom->getSectionRecord() == sect ) {
-                                                               //fprintf(stderr, "addr=0x%08X, atom=%s\n", atomAddr, atom->getDisplayName());
+                                                               //fprintf(stderr, "addr=0x%08llX, atom=%s\n", (uint64_t)atomAddr, atom->getDisplayName());
                                                                if ( (previousAtom != NULL) && (previousAtomAddr != atomAddr) ) {
                                                                        previousAtom->setSize(atomAddr - previousAtomAddr);
                                                                        if ( setFollowOnAtom && (atom != previousAtom) )
@@ -1726,7 +1772,7 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                if ( (sym.n_type() & N_STAB) == 0 ) {
                        if ( (sym.n_type() & N_TYPE) == N_UNDF ) {
                                const char* undefinedName = &fStrings[sym.n_strx()];
-                               if ( !fAppleObjc && (strncmp(undefinedName, ".objc_class_name_", 16) == 0) ) {
+                               if ( !fAppleObjc && (strncmp(undefinedName, ".objc_class_name_", 17) == 0) ) {
                                        fAppleObjc = true;
                                }
                                else if ( strncmp(undefinedName, "___dtrace_", 10) == 0 ) {
@@ -1759,7 +1805,6 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                        addReferencesForSection(sect);
        }
 
-
        // add objective-c references
        if ( fAppleObjc ) {
                for (const macho_section<P>* sect=sectionsStart; sect < sectionsEnd; ++sect) {
@@ -1791,14 +1836,40 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
        // add implicit direct reference from each C++ function to its eh info
        for (const macho_section<P>* sect=sectionsStart; sect < sectionsEnd; ++sect) {
                if ( ((sect->flags() & SECTION_TYPE) == S_COALESCED) && (strcmp(sect->sectname(), "__eh_frame") == 0) ) {
-                       for (std::map<uint32_t, BaseAtom*>::iterator it=fAddrToAtom.begin(); it != fAddrToAtom.end(); it++) {
+                       for (typename AddrToAtomMap::iterator it=fAddrToAtom.begin(); it != fAddrToAtom.end(); it++) {
                                // note: this algorithm depens on the map iterator returning entries in address order
                                if ( (it->first >= sect->addr()) && (it->first < sect->addr()+sect->size()) ) {
-                                       uint32_t ehAtomAddress = it->first;
+                                       pint_t ehAtomAddress = it->first;
                                        BaseAtom* ehAtom = it->second;
                                        const char* ehName = ehAtom->getName();
-                                       if ( (ehName != NULL) && (strcmp(&ehName[strlen(ehName)-3], ".eh") == 0) ) 
+                                       if ( (ehName != NULL) && (strcmp(&ehName[strlen(ehName)-3], ".eh") == 0) ) {
                                                makeReferenceToEH(ehName, ehAtomAddress, sect);
+                                               // make EH symbol static so linker does not try to coalesce
+                                               if ( fOptions.fForFinalLinkedImage )
+                                                       ehAtom->setScope(ObjectFile::Atom::scopeTranslationUnit);
+                                               // if it has a reference to a LSDA, add a group reference
+                                               std::vector<class ObjectFile::Reference*>& ehrefs = ehAtom->getReferences();
+                                               // all FDE's have at least 2 references (to CIE and to function)
+                                               if ( ehrefs.size() > 2 ) {
+                                                       // a third reference means there is a LSDA
+                                                       ObjectFile::Atom* lsdaAtom = NULL;
+                                                       for (std::vector<ObjectFile::Reference*>::iterator rit=ehrefs.begin(); rit != ehrefs.end(); rit++) {
+                                                               ObjectFile::Reference* ref = *rit;
+                                                               switch ( ref->getFixUpOffset() ) {
+                                                                       case 4:
+                                                                       case 8:
+                                                                               // these are CIE and function references
+                                                                               break;
+                                                                       default:
+                                                                               // this is LSDA reference
+                                                                               lsdaAtom =  &ref->getTarget();
+                                                               }
+                                                       }
+                                                       if ( lsdaAtom != NULL ) {
+                                                               new Reference<A>(A::kGroupSubordinate, AtomAndOffset(ehAtom), AtomAndOffset(lsdaAtom));
+                                                       }
+                                               }
+                                       }
                                }
                        }
                }
@@ -1847,7 +1918,7 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                }
        }
 
-       //for (std::map<uint32_t, BaseAtom*>::iterator it=fAddrToAtom.begin(); it != fAddrToAtom.end(); it++) {
+       //for (typename AddrToAtomMap::iterator it=fAddrToAtom.begin(); it != fAddrToAtom.end(); it++) {
        //      fprintf(stderr, "[0x%0X -> 0x%0llX) : %s\n", it->first, it->first+it->second->getSize(), it->second->getDisplayName());
        //}
 
@@ -1860,7 +1931,7 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                                // if can't parse dwarf, warn and give up
                                fDwarfTranslationUnitFile = NULL;
                                fDwarfTranslationUnitDir = NULL;
-                               fprintf(stderr, "ld: warning can't parse dwarf compilation unit info in %s\n", this->getPath());
+                               warning("can't parse dwarf compilation unit info in %s", this->getPath());
                                fDebugInfo = kDebugInfoNone;
                        }
                }
@@ -1948,7 +2019,7 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                                        line_free(lines);
                                }
                                else {
-                                       fprintf(stderr, "ld: warning could not parse dwarf line number info in %s\n", this->getPath());
+                                       warning("could not parse dwarf line number info in %s", this->getPath());
                                }
                        }
                }
@@ -1991,7 +2062,7 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                                                                        stab.string = symString;
                                                                }
                                                                else {
-                                                                       fprintf(stderr, "can't find atom for stabs BNSYM at %08llX in %s\n",
+                                                                       fprintf(stderr, "can't find atom for stabs BNSYM at %08llX in %s",
                                                                                (uint64_t)sym->n_value(), path);
                                                                }
                                                                break;
@@ -2031,7 +2102,7 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                                                                        }
                                                                }
                                                                if ( stab.atom == NULL ) {
-                                                                       fprintf(stderr, "can't find atom for N_GSYM stabs %s in %s\n", symString, path);
+                                                                       warning("can't find atom for N_GSYM stabs %s in %s", symString, path);
                                                                        useStab = false;
                                                                }
                                                                break;
@@ -2046,7 +2117,7 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                                                                        stab.string = symString;
                                                                }
                                                                else {
-                                                                       fprintf(stderr, "can't find atom for stabs FUN at %08llX in %s\n",
+                                                                       warning("can't find atom for stabs FUN at %08llX in %s",
                                                                                (uint64_t)currentAtomAddress, path);
                                                                }
                                                                break;
@@ -2062,7 +2133,7 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                                                                // -gfull built .o file
                                                                break;
                                                        default:
-                                                               fprintf(stderr, "unknown stabs type 0x%X in %s\n", type, path);
+                                                               warning("unknown stabs type 0x%X in %s", type, path);
                                                }
                                                break;
                                        case inBeginEnd:
@@ -2081,7 +2152,7 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                                                                        stab.string = symString;
                                                                }
                                                                else {
-                                                                       fprintf(stderr, "can't find atom for stabs 0x%X at %08llX in %s\n",
+                                                                       warning("can't find atom for stabs 0x%X at %08llX in %s",
                                                                                type, (uint64_t)sym->n_value(), path);
                                                                }
                                                                break;
@@ -2108,7 +2179,7 @@ Reader<A>::Reader(const uint8_t* fileContent, const char* path, time_t modTime,
                                                                                stab.string = symString;
                                                                        }
                                                                        else {
-                                                                               fprintf(stderr, "can't find atom for stabs FUN at %08llX in %s\n",
+                                                                               warning("can't find atom for stabs FUN at %08llX in %s",
                                                                                        (uint64_t)currentAtomAddress, path);
                                                                        }
                                                                }
@@ -2176,23 +2247,36 @@ void Reader<ppc>::setCpuConstraint(uint32_t cpusubtype)
 {
        switch (cpusubtype) {
                case CPU_SUBTYPE_POWERPC_ALL:
-                       fCpuConstraint = ObjectFile::Reader::kCpuAny;
-                       break;
                case CPU_SUBTYPE_POWERPC_750:
-                       fCpuConstraint = ObjectFile::Reader::kCpuG3;
-                       break;
                case CPU_SUBTYPE_POWERPC_7400:
                case CPU_SUBTYPE_POWERPC_7450:
-                       fCpuConstraint = ObjectFile::Reader::kCpuG4;
-                       break;
                case CPU_SUBTYPE_POWERPC_970:
-                       fCpuConstraint = ObjectFile::Reader::kCpuG5;
+                       fCpuConstraint = cpusubtype;
                        break;
                default:
-                       fprintf(stderr, "ld: warning, unknown cpu-sub-type 0x%08X in %s\n", cpusubtype, fPath);
+                       warning("unknown ppc subtype 0x%08X in %s, defaulting to ALL", cpusubtype, fPath);
+                       fCpuConstraint = CPU_SUBTYPE_POWERPC_ALL;
+            break;
        }
 }
 
+template <>
+void Reader<arm>::setCpuConstraint(uint32_t cpusubtype)
+{
+       switch (cpusubtype) {
+               case CPU_SUBTYPE_ARM_ALL:
+               case CPU_SUBTYPE_ARM_V4T:
+               case CPU_SUBTYPE_ARM_V5TEJ:
+               case CPU_SUBTYPE_ARM_V6:
+               case CPU_SUBTYPE_ARM_XSCALE:
+                       fCpuConstraint = cpusubtype;
+                       break;
+               default:
+                       warning("unknown arm subtype 0x%08X in %s, defaulting to ALL", cpusubtype, fPath);
+                       fCpuConstraint = CPU_SUBTYPE_ARM_ALL;
+            break;
+       }
+}
 
 template <typename A>
 void Reader<A>::setCpuConstraint(uint32_t cpusubtype)
@@ -2200,6 +2284,79 @@ void Reader<A>::setCpuConstraint(uint32_t cpusubtype)
        // no cpu sub types for this architecture
 }
 
+template <>
+uint32_t Reader<ppc>::updateCpuConstraint(uint32_t previous)
+{
+       switch ( previous ) {
+    case CPU_SUBTYPE_POWERPC_ALL:
+        return fCpuConstraint;
+        break;
+    case CPU_SUBTYPE_POWERPC_750:
+        if ( fCpuConstraint == CPU_SUBTYPE_POWERPC_7400 ||
+             fCpuConstraint == CPU_SUBTYPE_POWERPC_7450 ||
+             fCpuConstraint == CPU_SUBTYPE_POWERPC_970 )
+            return fCpuConstraint;
+        break;
+    case CPU_SUBTYPE_POWERPC_7400:
+    case CPU_SUBTYPE_POWERPC_7450:
+        if ( fCpuConstraint == CPU_SUBTYPE_POWERPC_970 )
+            return fCpuConstraint;
+        break;
+    case CPU_SUBTYPE_POWERPC_970:
+        // G5 can run everything
+        break;
+    default:
+        throw "Unhandled PPC cpu subtype!";
+        break;
+       }
+    return previous;
+}
+
+
+
+template <>
+uint32_t Reader<arm>::updateCpuConstraint(uint32_t previous)
+{
+    switch (previous) {
+               case CPU_SUBTYPE_ARM_ALL:
+                       return fCpuConstraint;
+                       break;
+               case CPU_SUBTYPE_ARM_V5TEJ:
+                       // v6 and xscale are more constrained than previous file (v5), so use it
+                       if (   (fCpuConstraint == CPU_SUBTYPE_ARM_V6)
+                               || (fCpuConstraint == CPU_SUBTYPE_ARM_XSCALE) )
+                               return fCpuConstraint;
+                       break;
+               case CPU_SUBTYPE_ARM_V4T:
+                       // v5, v6, and xscale are more constrained than previous file (v4t), so use it
+                       if (   (fCpuConstraint == CPU_SUBTYPE_ARM_V6)
+                               || (fCpuConstraint == CPU_SUBTYPE_ARM_V5TEJ)
+                               || (fCpuConstraint == CPU_SUBTYPE_ARM_XSCALE) )
+                               return fCpuConstraint;
+                       break;
+               case CPU_SUBTYPE_ARM_V6:
+                       // v6 can run everything except xscale
+                       if ( fCpuConstraint == CPU_SUBTYPE_ARM_XSCALE )
+                               throw "can't mix xscale and v6 code";
+                       break;
+               case CPU_SUBTYPE_ARM_XSCALE:
+                       // xscale can run everything except v6
+                       if ( fCpuConstraint == CPU_SUBTYPE_ARM_V6 )
+                               throw "can't mix xscale and v6 code";
+                       break;
+               default:
+                       throw "Unhandled ARM cpu subtype!";
+    }
+    return previous;
+}
+
+template <typename A>
+uint32_t Reader<A>::updateCpuConstraint(uint32_t current)
+{
+       // no cpu sub types for this architecture
+       return current;
+}
+
 template <typename A>
 void Reader<A>::addDtraceExtraInfos(uint32_t probeAddr, const char* providerName)
 {
@@ -2253,7 +2410,7 @@ template <typename A>
 BaseAtom* Reader<A>::findAtomByName(const char* name)
 {
        // first search the more important atoms
-       for (std::map<uint32_t, BaseAtom*>::iterator it=fAddrToAtom.begin(); it != fAddrToAtom.end(); it++) {
+       for (typename AddrToAtomMap::iterator it=fAddrToAtom.begin(); it != fAddrToAtom.end(); it++) {
                const char* atomName = it->second->getName();
                if ( (atomName != NULL) && (strcmp(atomName, name) == 0) ) {
                        return it->second;
@@ -2271,31 +2428,31 @@ BaseAtom* Reader<A>::findAtomByName(const char* name)
 }
 
 template <typename A>
-Reference<A>* Reader<A>::makeReference(Kinds kind, uint32_t atAddr, uint32_t toAddr)
+Reference<A>* Reader<A>::makeReference(Kinds kind, pint_t atAddr, pint_t toAddr)
 {
        return new Reference<A>(kind, findAtomAndOffset(atAddr), findAtomAndOffset(toAddr));
 }
 
 template <typename A>
-Reference<A>* Reader<A>::makeReference(Kinds kind, uint32_t atAddr, uint32_t fromAddr, uint32_t toAddr)
+Reference<A>* Reader<A>::makeReference(Kinds kind, pint_t atAddr, pint_t fromAddr, pint_t toAddr)
 {
        return new Reference<A>(kind, findAtomAndOffset(atAddr), findAtomAndOffset(fromAddr), findAtomAndOffset(toAddr));
 }
 
 template <typename A>
-Reference<A>* Reader<A>::makeReferenceWithToBase(Kinds kind, uint32_t atAddr, uint32_t toAddr, uint32_t toBaseAddr)
+Reference<A>* Reader<A>::makeReferenceWithToBase(Kinds kind, pint_t atAddr, pint_t toAddr, pint_t toBaseAddr)
 {
        return new Reference<A>(kind, findAtomAndOffset(atAddr), findAtomAndOffset(toBaseAddr, toAddr));
 }
 
 template <typename A>
-Reference<A>* Reader<A>::makeReferenceWithToBase(Kinds kind, uint32_t atAddr, uint32_t fromAddr, uint32_t toAddr, uint32_t toBaseAddr)
+Reference<A>* Reader<A>::makeReferenceWithToBase(Kinds kind, pint_t atAddr, pint_t fromAddr, pint_t toAddr, pint_t toBaseAddr)
 {
        return new Reference<A>(kind, findAtomAndOffset(atAddr), findAtomAndOffset(fromAddr), findAtomAndOffset(toBaseAddr, toAddr));
 }
 
 template <typename A>
-Reference<A>* Reader<A>::makeByNameReference(Kinds kind, uint32_t atAddr, const char* toName, uint32_t toOffset)
+Reference<A>* Reader<A>::makeByNameReference(Kinds kind, pint_t atAddr, const char* toName, uint32_t toOffset)
 {
        return new Reference<A>(kind, findAtomAndOffset(atAddr), toName, toOffset);
 }
@@ -2306,13 +2463,13 @@ Reference<A>* Reader<A>::makeReferenceToEH(const char* ehName, pint_t ehAtomAddr
        // add a direct reference from function atom to its eh frame atom
        const uint8_t* ehContent = (const uint8_t*)(fHeader) + ehAtomAddress - ehSect->addr() + ehSect->offset();
        int32_t deltaMinus8 = P::getP(*(pint_t*)(&ehContent[8]));       // offset 8 in eh info is delta to function
-       uint32_t funcAddr = ehAtomAddress + deltaMinus8 + 8;
-       return makeReference(A::kNoFixUp, funcAddr, ehAtomAddress);
+       pint_t funcAddr = ehAtomAddress + deltaMinus8 + 8;
+       return makeReference(A::kGroupSubordinate, funcAddr, ehAtomAddress);
 }
 
 
 template <>
-Reference<x86_64>* Reader<x86_64>::makeByNameReference(Kinds kind, uint32_t atAddr, const char* toName, uint32_t toOffset)
+Reference<x86_64>* Reader<x86_64>::makeByNameReference(Kinds kind, pint_t atAddr, const char* toName, uint32_t toOffset)
 {
        // x86_64 uses external relocations everywhere, so external relocations do not imply by-name references
        // instead check scope of target
@@ -2324,7 +2481,7 @@ Reference<x86_64>* Reader<x86_64>::makeByNameReference(Kinds kind, uint32_t atAd
 }
 
 template <>
-Reference<x86_64>* Reader<x86_64>::makeReferenceToSymbol(Kinds kind, uint32_t atAddr, const macho_nlist<P>* toSymbol, uint32_t toOffset)
+Reference<x86_64>* Reader<x86_64>::makeReferenceToSymbol(Kinds kind, pint_t atAddr, const macho_nlist<P>* toSymbol, pint_t toOffset)
 {
        // x86_64 uses external relocations everywhere, so external relocations do not imply by-name references
        // instead check scope of target
@@ -2346,26 +2503,30 @@ Reference<x86_64>* Reader<x86_64>::makeReferenceToEH(const char* ehName, pint_t
        const macho_relocation_info<P>* relocsEnd = &relocs[ehSect->nreloc()];
        for (const macho_relocation_info<P>* reloc = relocs; reloc < relocsEnd; ++reloc) {
                if ( (reloc->r_address() == ehAtomDeltaSectionOffset) && (reloc->r_type() == X86_64_RELOC_UNSIGNED) ) {
-                       uint32_t funcAddr = fSymbols[reloc->r_symbolnum()].n_value();
-                       return makeReference(x86_64::kNoFixUp, funcAddr, ehAtomAddress);
+                       pint_t funcAddr = fSymbols[reloc->r_symbolnum()].n_value();
+                       return makeReference(x86_64::kGroupSubordinate, funcAddr, ehAtomAddress);
                }
        }
-       fprintf(stderr, "ld: warning, can't find matching function for eh symbol %s\n", ehName);
+       warning("can't find matching function for eh symbol %s", ehName);
        return NULL;
 }
 
 
 template <typename A>
-AtomAndOffset Reader<A>::findAtomAndOffset(uint32_t addr)
+AtomAndOffset Reader<A>::findAtomAndOffset(pint_t addr)
 {
        // STL has no built-in for "find largest key that is same or less than"
-       std::map<uint32_t, BaseAtom*>::iterator it = fAddrToAtom.upper_bound(addr);
-       --it; // upper_bound gets us next key, so we back up one
+       typename AddrToAtomMap::iterator it = fAddrToAtom.upper_bound(addr);
+       // if no atoms up to this address return none found
+       if ( it == fAddrToAtom.begin() ) 
+               return AtomAndOffset(NULL);
+       // otherwise upper_bound gets us next key, so we back up one    
+       --it;
        AtomAndOffset result;
        result.atom = it->second;
        result.offset = addr - it->first;
-       //fprintf(stderr, "findAtomAndOffset(0x%0X) ==> %s (0x%0X -> 0x%0llX)\n",
-       //                      addr, result.atom->getDisplayName(), it->first, it->first+result.atom->getSize());
+       //fprintf(stderr, "findAtomAndOffset(0x%0llX) ==> %s (0x%0llX -> 0x%0llX)\n",
+       //                      (uint64_t)addr, result.atom->getDisplayName(), (uint64_t)it->first, it->first+result.atom->getSize());
        return result;
 }
 
@@ -2373,9 +2534,9 @@ AtomAndOffset Reader<A>::findAtomAndOffset(uint32_t addr)
 // baseAddr is the address of the target atom,
 // realAddr is the points into it
 template <typename A>
-AtomAndOffset Reader<A>::findAtomAndOffset(uint32_t baseAddr, uint32_t realAddr)
+AtomAndOffset Reader<A>::findAtomAndOffset(pint_t baseAddr, pint_t realAddr)
 {
-       std::map<uint32_t, BaseAtom*>::iterator it = fAddrToAtom.find(baseAddr);
+       typename AddrToAtomMap::iterator it = fAddrToAtom.find(baseAddr);
        if ( it != fAddrToAtom.end() ) {
                AtomAndOffset result;
                result.atom = it->second;
@@ -2718,6 +2879,18 @@ bool Reader<x86_64>::validFile(const uint8_t* fileContent)
        return true;
 }
 
+template <>
+bool Reader<arm>::validFile(const uint8_t* fileContent)
+{
+       const macho_header<P>* header = (const macho_header<P>*)fileContent;
+       if ( header->magic() != MH_MAGIC )
+               return false;
+       if ( header->cputype() != CPU_TYPE_ARM )
+               return false;
+       if ( header->filetype() != MH_OBJECT )
+               return false;
+       return true;
+}
 
 template <typename A>
 bool Reader<A>::isWeakImportSymbol(const macho_nlist<P>* sym)
@@ -2834,7 +3007,7 @@ bool Reader<A>::addRelocReference_powerpc(const macho_section<typename A::P>* se
                        case PPC_RELOC_LO16:
                                {
                                        if ( nextReloc->r_type() != PPC_RELOC_PAIR ) {
-                                               printf("PPC_RELOC_LO16 missing following pair\n");
+                                               warning("PPC_RELOC_LO16 missing following pair");
                                                break;
                                        }
                                        result = true;
@@ -2847,7 +3020,7 @@ bool Reader<A>::addRelocReference_powerpc(const macho_section<typename A::P>* se
                                                dstAddr = (nextReloc->r_address() << 16) + ((uint32_t)lowBits & 0x0000FFFF);
                                                if ( reloc->r_symbolnum() == R_ABS ) {
                                                        // find absolute symbol that corresponds to pointerValue
-                                                       std::map<uint32_t, BaseAtom*>::iterator pos = fAddrToAbsoluteAtom.find(dstAddr);
+                                                       typename AddrToAtomMap::iterator pos = fAddrToAbsoluteAtom.find(dstAddr);
                                                        if ( pos != fAddrToAbsoluteAtom.end() ) 
                                                                makeByNameReference(A::kAbsLow16, srcAddr, pos->second->getName(), 0);
                                                        else
@@ -2862,7 +3035,7 @@ bool Reader<A>::addRelocReference_powerpc(const macho_section<typename A::P>* se
                        case PPC_RELOC_LO14:
                                {
                                        if ( nextReloc->r_type() != PPC_RELOC_PAIR ) {
-                                               printf("PPC_RELOC_LO14 missing following pair\n");
+                                               warning("PPC_RELOC_LO14 missing following pair");
                                                break;
                                        }
                                        result = true;
@@ -2875,7 +3048,7 @@ bool Reader<A>::addRelocReference_powerpc(const macho_section<typename A::P>* se
                                                dstAddr = (nextReloc->r_address() << 16) | ((uint32_t)lowBits & 0x0000FFFF);
                                                if ( reloc->r_symbolnum() == R_ABS ) {
                                                        // find absolute symbol that corresponds to pointerValue
-                                                       std::map<uint32_t, BaseAtom*>::iterator pos = fAddrToAbsoluteAtom.find(dstAddr);
+                                                       typename AddrToAtomMap::iterator pos = fAddrToAbsoluteAtom.find(dstAddr);
                                                        if ( pos != fAddrToAbsoluteAtom.end() ) 
                                                                makeByNameReference(A::kAbsLow14, srcAddr, pos->second->getName(), 0);
                                                        else
@@ -2890,7 +3063,7 @@ bool Reader<A>::addRelocReference_powerpc(const macho_section<typename A::P>* se
                        case PPC_RELOC_HI16:
                                {
                                        if ( nextReloc->r_type() != PPC_RELOC_PAIR ) {
-                                               printf("PPC_RELOC_HI16 missing following pair\n");
+                                               warning("PPC_RELOC_HI16 missing following pair");
                                                break;
                                        }
                                        result = true;
@@ -2902,7 +3075,7 @@ bool Reader<A>::addRelocReference_powerpc(const macho_section<typename A::P>* se
                                                dstAddr = ((instruction & 0x0000FFFF) << 16) | (nextReloc->r_address() & 0x0000FFFF);
                                                if ( reloc->r_symbolnum() == R_ABS ) {
                                                        // find absolute symbol that corresponds to pointerValue
-                                                       std::map<uint32_t, BaseAtom*>::iterator pos = fAddrToAbsoluteAtom.find(dstAddr);
+                                                       typename AddrToAtomMap::iterator pos = fAddrToAbsoluteAtom.find(dstAddr);
                                                        if ( pos != fAddrToAbsoluteAtom.end() ) 
                                                                makeByNameReference(A::kAbsHigh16, srcAddr, pos->second->getName(), 0);
                                                        else
@@ -2917,7 +3090,7 @@ bool Reader<A>::addRelocReference_powerpc(const macho_section<typename A::P>* se
                        case PPC_RELOC_HA16:
                                {
                                        if ( nextReloc->r_type() != PPC_RELOC_PAIR ) {
-                                               printf("PPC_RELOC_HA16 missing following pair\n");
+                                               warning("PPC_RELOC_HA16 missing following pair");
                                                break;
                                        }
                                        result = true;
@@ -2930,7 +3103,7 @@ bool Reader<A>::addRelocReference_powerpc(const macho_section<typename A::P>* se
                                                dstAddr = ((instruction & 0x0000FFFF) << 16) + (int32_t)lowBits;
                                                if ( reloc->r_symbolnum() == R_ABS ) {
                                                        // find absolute symbol that corresponds to pointerValue
-                                                       std::map<uint32_t, BaseAtom*>::iterator pos = fAddrToAbsoluteAtom.find(dstAddr);
+                                                       typename AddrToAtomMap::iterator pos = fAddrToAbsoluteAtom.find(dstAddr);
                                                        if ( pos != fAddrToAbsoluteAtom.end() ) 
                                                                makeByNameReference(A::kAbsHigh16AddLow, srcAddr, pos->second->getName(), 0);
                                                        else
@@ -2959,9 +3132,10 @@ bool Reader<A>::addRelocReference_powerpc(const macho_section<typename A::P>* se
                        case PPC_RELOC_JBSR:
                                // this is from -mlong-branch codegen.  We ignore the jump island and make reference to the real target
                                if ( nextReloc->r_type() != PPC_RELOC_PAIR ) {
-                                       printf("PPC_RELOC_JBSR missing following pair\n");
+                                       warning("PPC_RELOC_JBSR missing following pair");
                                        break;
                                }
+                               fHasLongBranchStubs = true;
                                result = true;
                                makeReference(A::kBranch24, srcAddr, nextReloc->r_address());
                                if ( (instruction & 0x4C000000) == 0x48000000 ) {
@@ -2977,7 +3151,7 @@ bool Reader<A>::addRelocReference_powerpc(const macho_section<typename A::P>* se
                                }
                                break;
                        default:
-                               printf("unknown relocation type %d\n", reloc->r_type());
+                               warning("unknown relocation type %d", reloc->r_type());
                }
        }
        else {
@@ -3042,7 +3216,7 @@ bool Reader<A>::addRelocReference_powerpc(const macho_section<typename A::P>* se
                        case PPC_RELOC_LO16_SECTDIFF:
                                {
                                        if ( ! nextRelocIsPair ) {
-                                               printf("PPC_RELOC_LO16_SECTDIFF missing following PAIR\n");
+                                               warning("PPC_RELOC_LO16_SECTDIFF missing following PAIR");
                                                break;
                                        }
                                        instruction = BigEndian::get32(*fixUpPtr);
@@ -3054,7 +3228,7 @@ bool Reader<A>::addRelocReference_powerpc(const macho_section<typename A::P>* se
                        case PPC_RELOC_LO14_SECTDIFF:
                                {
                                        if ( ! nextRelocIsPair ) {
-                                               printf("PPC_RELOC_LO14_SECTDIFF missing following PAIR\n");
+                                               warning("PPC_RELOC_LO14_SECTDIFF missing following PAIR");
                                                break;
                                        }
                                        instruction = BigEndian::get32(*fixUpPtr);
@@ -3066,7 +3240,7 @@ bool Reader<A>::addRelocReference_powerpc(const macho_section<typename A::P>* se
                        case PPC_RELOC_HA16_SECTDIFF:
                                {
                                        if ( ! nextRelocIsPair ) {
-                                               printf("PPC_RELOC_HA16_SECTDIFF missing following PAIR\n");
+                                               warning("PPC_RELOC_HA16_SECTDIFF missing following PAIR");
                                                break;
                                        }
                                        instruction = BigEndian::get32(*fixUpPtr);
@@ -3078,7 +3252,7 @@ bool Reader<A>::addRelocReference_powerpc(const macho_section<typename A::P>* se
                        case PPC_RELOC_LO14:
                                {
                                        if ( ! nextRelocIsPair ) {
-                                               printf("PPC_RELOC_LO14 missing following PAIR\n");
+                                               warning("PPC_RELOC_LO14 missing following PAIR");
                                                break;
                                        }
                                        instruction = BigEndian::get32(*fixUpPtr);
@@ -3090,7 +3264,7 @@ bool Reader<A>::addRelocReference_powerpc(const macho_section<typename A::P>* se
                        case PPC_RELOC_LO16:
                                {
                                        if ( ! nextRelocIsPair ) {
-                                               printf("PPC_RELOC_LO16 missing following PAIR\n");
+                                               warning("PPC_RELOC_LO16 missing following PAIR");
                                                break;
                                        }
                                        instruction = BigEndian::get32(*fixUpPtr);
@@ -3102,7 +3276,7 @@ bool Reader<A>::addRelocReference_powerpc(const macho_section<typename A::P>* se
                        case PPC_RELOC_HA16:
                                {
                                        if ( ! nextRelocIsPair ) {
-                                               printf("PPC_RELOC_HA16 missing following PAIR\n");
+                                               warning("PPC_RELOC_HA16 missing following PAIR");
                                                break;
                                        }
                                        instruction = BigEndian::get32(*fixUpPtr);
@@ -3111,84 +3285,76 @@ bool Reader<A>::addRelocReference_powerpc(const macho_section<typename A::P>* se
                                        makeReferenceWithToBase(A::kAbsHigh16AddLow, srcAddr, betterDstAddr, dstAddr);
                                }
                                break;
+                       case PPC_RELOC_HI16:
+                               {
+                                       if ( ! nextRelocIsPair ) {
+                                               warning("PPC_RELOC_HI16 missing following PAIR");
+                                               break;
+                                       }
+                                       instruction = BigEndian::get32(*fixUpPtr);
+                                       lowBits = (nextRelocAddress & 0xFFFF);
+                                       betterDstAddr = ((instruction & 0xFFFF) << 16) | (lowBits & 0x0000FFFF);
+                                       makeReferenceWithToBase(A::kAbsHigh16, srcAddr, betterDstAddr, dstAddr);
+                               }
+                               break;
                        case PPC_RELOC_SECTDIFF:
                        case PPC_RELOC_LOCAL_SECTDIFF:
                                {
                                        if ( ! nextRelocIsPair ) {
-                                               printf("PPC_RELOC_SECTDIFF missing following pair\n");
+                                               warning("PPC_RELOC_SECTDIFF missing following pair");
                                                break;
                                        }
-                                       // need to read section content to see if this has an addend, if so adjust addresses
+                                       Kinds kind = A::kPointerDiff32;;
+                                       uint32_t contentAddr = 0;
                                        switch ( sreloc->r_length() ) {
                                                case 0:
-                                                       if ( (dstAddr - nextRelocValue) != *((uint8_t*)fixUpPtr) ) {
-                                                               if (findAtomAndOffset(dstAddr).atom == findAtomAndOffset(srcAddr).atom )
-                                                                       dstAddr = *((uint8_t*)fixUpPtr) + nextRelocValue;
-                                                               else
-                                                                       nextRelocValue = dstAddr - *((uint8_t*)fixUpPtr);
-                                                       }
-                                                       break;
+                                                       throw "bad diff relocations r_length (0) for ppc architecture";
                                                case 1:
-                                                       if ( (dstAddr - nextRelocValue) != BigEndian::get16(*((uint16_t*)fixUpPtr)) ) {
-                                                               if (findAtomAndOffset(dstAddr).atom == findAtomAndOffset(srcAddr).atom )
-                                                                       dstAddr = BigEndian::get16(*((uint16_t*)fixUpPtr)) + nextRelocValue;
-                                                               else
-                                                                       nextRelocValue = dstAddr - BigEndian::get16(*((uint16_t*)fixUpPtr));
-                                                       }
+                                                       kind = A::kPointerDiff16;
+                                                       contentAddr = BigEndian::get16(*((uint16_t*)fixUpPtr));
                                                        break;
                                                case 2:
-                                                       if ( (dstAddr - nextRelocValue) != BigEndian::get32(*fixUpPtr) ) {
-                                                               if (findAtomAndOffset(dstAddr).atom == findAtomAndOffset(srcAddr).atom )
-                                                                       dstAddr = BigEndian::get32(*fixUpPtr) + nextRelocValue;
-                                                               else
-                                                                       nextRelocValue = dstAddr - BigEndian::get32(*fixUpPtr);
-                                                       }
+                                                       kind = A::kPointerDiff32;
+                                                       contentAddr = BigEndian::get32(*fixUpPtr);
                                                        break;
                                                case 3:
-                                                       if ( (dstAddr - nextRelocValue) != BigEndian::get64(*((uint64_t*)fixUpPtr)) ) {
-                                                               if (findAtomAndOffset(dstAddr).atom == findAtomAndOffset(srcAddr).atom )
-                                                                       dstAddr = BigEndian::get64(*((uint64_t*)fixUpPtr)) + nextRelocValue;
-                                                               else
-                                                                       nextRelocValue = dstAddr - BigEndian::get64(*((uint64_t*)fixUpPtr));
-                                                       }
+                                                       kind = A::kPointerDiff64;
+                                                       contentAddr = BigEndian::get64(*((uint64_t*)fixUpPtr));
                                                        break;
                                        }
-                                       makeReference(pointerDiffKindForLength_powerpc(sreloc->r_length()), srcAddr, nextRelocValue, dstAddr);
+                                       AtomAndOffset srcao  = findAtomAndOffset(srcAddr);
+                                       AtomAndOffset fromao = findAtomAndOffset(nextRelocValue);
+                                       AtomAndOffset toao   = findAtomAndOffset(dstAddr);
+                                       // check for addend encoded in the section content
+                                       //fprintf(stderr, "addRef: dstAddr=0x%X, nextRelocValue=0x%X, contentAddr=0x%X\n",
+                                       //              dstAddr, nextRelocValue, contentAddr);
+                                       if ( (dstAddr - nextRelocValue) != contentAddr ) {
+                                               if ( toao.atom == srcao.atom )
+                                                       toao.offset += (contentAddr + nextRelocValue) - dstAddr;
+                                               else if ( fromao.atom == srcao.atom )
+                                                       toao.offset += (contentAddr + nextRelocValue) - dstAddr;
+                                               else
+                                                       fromao.offset += (dstAddr - contentAddr) - nextRelocValue;
+                                       }
+                                       //fprintf(stderr, "addRef: src=%s+0x%X, from=%s+0x%X, to=%s+0x%X\n",
+                                       //      srcao.atom->getDisplayName(), srcao.offset, 
+                                       //      fromao.atom->getDisplayName(), fromao.offset, 
+                                       //      toao.atom->getDisplayName(), toao.offset);
+                                       new Reference<A>(kind, srcao, fromao, toao);
                                }
                                break;
                        case PPC_RELOC_PAIR:
                                break;
                        case PPC_RELOC_HI16_SECTDIFF:
-                               printf("unexpected scattered relocation type PPC_RELOC_HI16_SECTDIFF\n");
+                               warning("unexpected scattered relocation type PPC_RELOC_HI16_SECTDIFF");
                                break;
                        default:
-                               printf("unknown scattered relocation type %d\n", sreloc->r_type());
+                               warning("unknown scattered relocation type %d", sreloc->r_type());
                }
        }
        return result;
 }
 
-template <>
-ppc::ReferenceKinds Reader<ppc>::pointerDiffKindForLength_powerpc(uint8_t r_length)
-{
-       if ( r_length == 2 )
-               return ppc::kPointerDiff32;
-       else if ( r_length == 1 )
-               return ppc::kPointerDiff16;
-       else
-               throw "bad diff relocations r_length for ppc architecture";
- }
-
-template <>
-ppc64::ReferenceKinds Reader<ppc64>::pointerDiffKindForLength_powerpc(uint8_t r_length)
-{
-       if ( r_length == 2 )
-               return ppc64::kPointerDiff32;
-       else if ( r_length == 3 )
-               return ppc64::kPointerDiff64;
-       else
-               throw "bad diff relocations r_length for ppc64 architecture";
- }
 
 template <>
 bool Reader<x86>::addRelocReference(const macho_section<x86::P>* sect, const macho_relocation_info<x86::P>* reloc)
@@ -3208,8 +3374,9 @@ bool Reader<x86>::addRelocReference(const macho_section<x86::P>* sect, const mac
                                        if ( reloc->r_pcrel() ) {
                                                switch( reloc->r_length() ) {
                                                        case 0:
-                                                       case 3:
-                                                               throw "bad pc-rel vanilla relocation length";
+                                                               kind = x86::kPCRel8;
+                                                               pointerValue = srcAddr + *((int8_t*)fixUpPtr) + sizeof(int8_t);
+                                                               break;
                                                        case 1:
                                                                kind = x86::kPCRel16;
                                                                pointerValue = srcAddr + (int16_t)E::get16(*((uint16_t*)fixUpPtr)) + sizeof(uint16_t);
@@ -3218,6 +3385,8 @@ bool Reader<x86>::addRelocReference(const macho_section<x86::P>* sect, const mac
                                                                kind = x86::kPCRel32;
                                                                pointerValue += srcAddr + sizeof(uint32_t);
                                                                break;
+                                                       case 3:
+                                                               throw "bad pc-rel vanilla relocation length";
                                                }
                                        }
                                        else if ( strcmp(sect->segname(), "__TEXT") == 0 ) {
@@ -3232,8 +3401,12 @@ bool Reader<x86>::addRelocReference(const macho_section<x86::P>* sect, const mac
                                        }
                                        if ( reloc->r_extern() ) {
                                                const macho_nlist<P>* targetSymbol = &fSymbols[reloc->r_symbolnum()];
-                                               if ( this->isWeakImportSymbol(targetSymbol) )
-                                                       kind = x86::kPointerWeakImport;
+                                               if ( this->isWeakImportSymbol(targetSymbol) ) {
+                                                       if ( reloc->r_pcrel() )
+                                                               kind = x86::kPCRel32WeakImport;
+                                                       else
+                                                               kind = x86::kPointerWeakImport;
+                                               }
                                                const char* targetName = &fStrings[targetSymbol->n_strx()];
                                                if ( strncmp(targetName, "___dtrace_probe$", 16) == 0 ) {
                                                        makeByNameReference(x86::kDtraceProbeSite, srcAddr, targetName, 0);
@@ -3265,7 +3438,7 @@ bool Reader<x86>::addRelocReference(const macho_section<x86::P>* sect, const mac
                                                        makeReference(kind, srcAddr, pointerValue);
                                                else {
                                                        // find absolute symbol that corresponds to pointerValue
-                                                       std::map<uint32_t, BaseAtom*>::iterator pos = fAddrToAbsoluteAtom.find(pointerValue);
+                                                       AddrToAtomMap::iterator pos = fAddrToAbsoluteAtom.find(pointerValue);
                                                        if ( pos != fAddrToAbsoluteAtom.end() ) 
                                                                makeByNameReference(kind, srcAddr, pos->second->getName(), 0);
                                                        else
@@ -3275,7 +3448,7 @@ bool Reader<x86>::addRelocReference(const macho_section<x86::P>* sect, const mac
                                }
                                break;
                        default:
-                               printf("unknown relocation type %d\n", reloc->r_type());
+                               warning("unknown relocation type %d", reloc->r_type());
                }
        }
        else {
@@ -3290,15 +3463,15 @@ bool Reader<x86>::addRelocReference(const macho_section<x86::P>* sect, const mac
                bool nextRelocIsPair = false;
                uint32_t nextRelocAddress = 0;
                uint32_t nextRelocValue = 0;
-               if ( (nextReloc->r_address() & R_SCATTERED) == 0 ) {
-                       if ( nextReloc->r_type() == PPC_RELOC_PAIR ) {
+               if ( (nextReloc->r_address() & R_SCATTERED) == 0 ) {
+                       if ( nextReloc->r_type() == GENERIC_RELOC_PAIR ) {
                                nextRelocIsPair = true;
                                nextRelocAddress = nextReloc->r_address();
                                result = true;
                        }
                }
                else {
-                       if ( nextSReloc->r_type() == PPC_RELOC_PAIR ) {
+                       if ( nextSReloc->r_type() == GENERIC_RELOC_PAIR ) {
                                nextRelocIsPair = true;
                                nextRelocAddress = nextSReloc->r_address();
                                nextRelocValue = nextSReloc->r_value();
@@ -3324,7 +3497,7 @@ bool Reader<x86>::addRelocReference(const macho_section<x86::P>* sect, const mac
                        case GENERIC_RELOC_LOCAL_SECTDIFF:
                                {
                                        if ( !nextRelocIsPair ) {
-                                               printf("GENERIC_RELOC_SECTDIFF missing following pair\n");
+                                               warning("GENERIC_RELOC_SECTDIFF missing following pair");
                                                break;
                                        }
                                        x86::ReferenceKinds kind = x86::kPointerDiff;
@@ -3367,7 +3540,7 @@ bool Reader<x86>::addRelocReference(const macho_section<x86::P>* sect, const mac
                                // do nothing, already used via a look ahead
                                break;
                        default:
-                               printf("unknown scattered relocation type %d\n", sreloc->r_type());
+                               warning("unknown scattered relocation type %d", sreloc->r_type());
                }
        }
        return result;
@@ -3490,25 +3663,37 @@ bool Reader<x86_64>::addRelocReference(const macho_section<x86_64::P>* sect, con
                case X86_64_RELOC_BRANCH:
                        if ( ! reloc->r_pcrel() )
                                throw "not pcrel and X86_64_RELOC_BRANCH not supported";
-                       if ( reloc->r_length() != 2 ) 
-                               throw "length != 2 and X86_64_RELOC_BRANCH not supported";
-                       dstAddr = (int64_t)((int32_t)(E::get32(*fixUpPtr)));
-                       if ( reloc->r_extern() ) {
-                               if ( strncmp(targetName, "___dtrace_probe$", 16) == 0 ) {
-                                       makeByNameReference(x86_64::kDtraceProbeSite, srcAddr, targetName, 0);
-                                       addDtraceExtraInfos(srcAddr, &targetName[16]);
+                       if ( reloc->r_length() == 2 ) {
+                               dstAddr = (int64_t)((int32_t)(E::get32(*fixUpPtr)));
+                               if ( reloc->r_extern() ) {
+                                       if ( strncmp(targetName, "___dtrace_probe$", 16) == 0 ) {
+                                               makeByNameReference(x86_64::kDtraceProbeSite, srcAddr, targetName, 0);
+                                               addDtraceExtraInfos(srcAddr, &targetName[16]);
+                                       }
+                                       else if ( strncmp(targetName, "___dtrace_isenabled$", 20) == 0 ) {
+                                               makeByNameReference(x86_64::kDtraceIsEnabledSite, srcAddr, targetName, 0);
+                                               addDtraceExtraInfos(srcAddr, &targetName[16]);
+                                       }
+                                       else if ( isWeakImportSymbol(targetSymbol) )
+                                               makeReferenceToSymbol(x86_64::kBranchPCRel32WeakImport, srcAddr, targetSymbol, dstAddr);
+                                       else
+                                               makeReferenceToSymbol(x86_64::kBranchPCRel32, srcAddr, targetSymbol, dstAddr);
                                }
-                               else if ( strncmp(targetName, "___dtrace_isenabled$", 20) == 0 ) {
-                                       makeByNameReference(x86_64::kDtraceIsEnabledSite, srcAddr, targetName, 0);
-                                       addDtraceExtraInfos(srcAddr, &targetName[16]);
+                               else {
+                                       makeReference(x86_64::kBranchPCRel32, srcAddr, srcAddr+4+dstAddr);
+                               }
+                       }
+                       else if ( reloc->r_length() == 0 ) {
+                               dstAddr = *((int8_t*)fixUpPtr);
+                               if ( reloc->r_extern() ) {
+                                       makeReferenceToSymbol(x86_64::kBranchPCRel8, srcAddr, targetSymbol, dstAddr);
+                               }
+                               else {
+                                       makeReference(x86_64::kBranchPCRel8, srcAddr, srcAddr+1+dstAddr);
                                }
-                               else if ( isWeakImportSymbol(targetSymbol) )
-                                       makeReferenceToSymbol(x86_64::kBranchPCRel32WeakImport, srcAddr, targetSymbol, dstAddr);
-                               else
-                                       makeReferenceToSymbol(x86_64::kBranchPCRel32, srcAddr, targetSymbol, dstAddr);
                        }
                        else {
-                               makeReference(x86_64::kBranchPCRel32, srcAddr, srcAddr+4+dstAddr);
+                               throwf("length=%d and X86_64_RELOC_BRANCH not supported", reloc->r_length());;
                        }
                        break;
                case X86_64_RELOC_GOT:
@@ -3603,12 +3788,273 @@ bool Reader<x86_64>::addRelocReference(const macho_section<x86_64::P>* sect, con
                        break;
                }
                default:
-                       fprintf(stderr, "unknown relocation type %d\n", reloc->r_type());
+                       warning("unknown relocation type %d", reloc->r_type());
        }
        return result;
 }
 
 
+/// Reader<arm>::addRelocReference - 
+/// turns arm relocation entries into references.  Returns true if the next
+/// relocation should be skipped, false otherwise.
+template <>
+bool Reader<arm>::addRelocReference(const macho_section<arm::P>* sect, 
+                                    const macho_relocation_info<arm::P>* reloc)
+{
+       uint32_t *  fixUpPtr;
+       int32_t         displacement;                                                                                           
+       uint32_t    instruction = 0;
+       bool        result = false;
+       uint32_t        srcAddr;
+       uint32_t        dstAddr;
+       uint32_t        pointerValue;
+       
+       if ( (reloc->r_address() & R_SCATTERED) == 0 ) {
+               // non-scattered relocation
+               const char* targetName = NULL;
+               bool        weakImport = false;
+    
+               srcAddr = sect->addr() + reloc->r_address();
+               fixUpPtr = (uint32_t*)((char*)(fHeader) + sect->offset() + reloc->r_address());
+               if ( reloc->r_type() != ARM_RELOC_PAIR )
+                       instruction = LittleEndian::get32(*fixUpPtr);
+    
+               if ( reloc->r_extern() ) {
+                       const macho_nlist<P>* targetSymbol = &fSymbols[reloc->r_symbolnum()];
+                       targetName = &fStrings[targetSymbol->n_strx()];
+                       weakImport = this->isWeakImportSymbol(targetSymbol);
+               }
+    
+               switch ( reloc->r_type() ) {
+                       case ARM_RELOC_BR24:
+                               // Sign-extend displacement
+                               displacement = (instruction & 0x00FFFFFF) << 2;
+                               if ( (displacement & 0x02000000) != 0 )
+                                       displacement |= 0xFC000000;
+                               // The pc added will be +8 from the pc
+                               displacement += 8;
+                               // If this is BLX add H << 1
+                               if ((instruction & 0xFE000000) == 0xFA000000)
+                                       displacement += ((instruction & 0x01000000) >> 23);
+
+                               if ( reloc->r_extern() ) {
+                                       uint32_t offsetInTarget = srcAddr + displacement;
+                                       if ( strncmp(targetName, "___dtrace_probe$", 16) == 0 ) {
+                                               makeByNameReference(arm::kDtraceProbeSite, srcAddr, targetName, 0);
+                                               addDtraceExtraInfos(srcAddr, &targetName[16]);
+                                       }
+                                       else if ( strncmp(targetName, "___dtrace_isenabled$", 20) == 0 ) {
+                                               makeByNameReference(arm::kDtraceIsEnabledSite, srcAddr, targetName, 0);
+                                               addDtraceExtraInfos(srcAddr, &targetName[20]);
+                                       }
+                                       else if ( weakImport )
+                                               makeByNameReference(arm::kBranch24WeakImport, srcAddr, targetName, offsetInTarget);
+                                       else
+                                               makeByNameReference(arm::kBranch24, srcAddr, targetName, offsetInTarget);
+                               }
+                               else {
+                                       dstAddr = srcAddr + displacement;
+                                       ObjectFile::Atom* atom = findAtomAndOffset(dstAddr).atom;
+                                       // check for dtrace probes and weak_import stubs 
+                                       const char* targetName = atom->getName();
+                                       if ( (targetName != NULL) && (strncmp(targetName, "___dtrace_probe$", 16) == 0) ) {
+                                               makeByNameReference(arm::kDtraceProbeSite, srcAddr, targetName, 0);
+                                               addDtraceExtraInfos(srcAddr, &targetName[16]);
+                                       }
+                                       else if ( (targetName != NULL) && (strncmp(targetName, "___dtrace_isenabled$", 20) == 0) ) {
+                                               makeByNameReference(arm::kDtraceIsEnabledSite, srcAddr, targetName, 0);
+                                               addDtraceExtraInfos(srcAddr, &targetName[20]);
+                                       }
+                                       else if ( (atom->getSymbolTableInclusion() == ObjectFile::Atom::kSymbolTableNotIn)
+                                               && ((AnonymousAtom<x86>*)atom)->isWeakImportStub() )
+                                               makeReference(arm::kBranch24WeakImport, srcAddr, dstAddr);
+                                       else if ( reloc->r_symbolnum() != R_ABS )
+                                               makeReference(arm::kBranch24, srcAddr, dstAddr);
+                                       else {
+                                               // find absolute symbol that corresponds to pointerValue
+                                               AddrToAtomMap::iterator pos = fAddrToAbsoluteAtom.find(dstAddr);
+                                               if ( pos != fAddrToAbsoluteAtom.end() ) 
+                                                       makeByNameReference(arm::kBranch24, srcAddr, pos->second->getName(), 0);
+                                               else
+                                                       throwf("R_ABS reloc but no absolute symbol at target address");
+                                       }
+                               }
+                               break;
+       
+                       case ARM_THUMB_RELOC_BR22:
+                               // First instruction has upper 11 bits of the displacement.
+                               displacement = (instruction & 0x7FF) << 12;
+                               if ( (displacement & 0x400000) != 0 )
+                                       displacement |= 0xFF800000;
+                               // Second instruction has lower eleven bits of the displacement.
+                               displacement += ((instruction >> 16) & 0x7FF) << 1;
+                               // The pc added will be +4 from the pc
+                               displacement += 4;
+                               // If the instruction was blx, force the low 2 bits to be clear
+                               dstAddr = srcAddr + displacement;
+                               if ((instruction & 0xF8000000) == 0xE8000000)
+                                       dstAddr &= 0xFFFFFFFC;
+
+                               if ( reloc->r_extern() ) {
+                                       uint32_t offsetInTarget = dstAddr;
+                                       if ( strncmp(targetName, "___dtrace_probe$", 16) == 0 ) {
+                                               makeByNameReference(arm::kDtraceProbeSite, srcAddr, targetName, 0);
+                                               addDtraceExtraInfos(srcAddr, &targetName[16]);
+                                       }
+                                       else if ( strncmp(targetName, "___dtrace_isenabled$", 20) == 0 ) {
+                                               makeByNameReference(arm::kDtraceIsEnabledSite, srcAddr, targetName, 0);
+                                               addDtraceExtraInfos(srcAddr, &targetName[20]);
+                                       }
+                                       else if ( weakImport )
+                                               makeByNameReference(arm::kThumbBranch22WeakImport, srcAddr, targetName, offsetInTarget);
+                                       else
+                                               makeByNameReference(arm::kThumbBranch22, srcAddr, targetName, offsetInTarget);
+                               }
+                               else {
+                                       ObjectFile::Atom* atom = findAtomAndOffset(dstAddr).atom;
+                                       // check for dtrace probes and weak_import stubs 
+                                       const char* targetName = atom->getName();
+                                       if ( (targetName != NULL) && (strncmp(targetName, "___dtrace_probe$", 16) == 0) ) {
+                                               makeByNameReference(arm::kDtraceProbeSite, srcAddr, targetName, 0);
+                                               addDtraceExtraInfos(srcAddr, &targetName[16]);
+                                       }
+                                       else if ( (targetName != NULL) && (strncmp(targetName, "___dtrace_isenabled$", 20) == 0) ) {
+                                               makeByNameReference(arm::kDtraceIsEnabledSite, srcAddr, targetName, 0);
+                                               addDtraceExtraInfos(srcAddr, &targetName[20]);
+                                       }
+                                       else if ( (atom->getSymbolTableInclusion() == ObjectFile::Atom::kSymbolTableNotIn)
+                                               && ((AnonymousAtom<x86>*)atom)->isWeakImportStub() )
+                                               makeReference(arm::kThumbBranch22WeakImport, srcAddr, dstAddr);
+                                       else if ( reloc->r_symbolnum() != R_ABS )
+                                               makeReference(arm::kThumbBranch22, srcAddr, dstAddr);
+                                       else {
+                                               // find absolute symbol that corresponds to pointerValue
+                                               AddrToAtomMap::iterator pos = fAddrToAbsoluteAtom.find(dstAddr);
+                                               if ( pos != fAddrToAbsoluteAtom.end() ) 
+                                                       makeByNameReference(arm::kThumbBranch22, srcAddr, pos->second->getName(), 0);
+                                               else
+                                                       throwf("R_ABS reloc but no absolute symbol at target address");
+                                       }
+                               }
+                               break;
+
+                       case ARM_RELOC_VANILLA:
+                               if ( reloc->r_length() != 2 )
+                                       throw "bad length for ARM_RELOC_VANILLA";
+
+                               pointerValue = instruction;
+                               if ( reloc->r_extern() ) {
+                                       if ( weakImport )
+                                               makeByNameReference(arm::kPointerWeakImport, srcAddr, targetName, pointerValue);
+                                       else
+                                               makeByNameReference(arm::kPointer, srcAddr, targetName, pointerValue);
+                               }
+                               else {
+                                       makeReference(arm::kPointer, srcAddr, pointerValue);
+                               }
+                               break;
+                               
+                       default:
+                               warning("unexpected relocation type %u", reloc->r_type());
+                               break;
+               }
+       } 
+       else {
+               const macho_scattered_relocation_info<P>* sreloc = (macho_scattered_relocation_info<P>*)reloc;
+               const macho_scattered_relocation_info<P>* nextSReloc = &sreloc[1];
+               srcAddr = sect->addr() + sreloc->r_address();
+               dstAddr = sreloc->r_value();
+               uint32_t betterDstAddr;
+               fixUpPtr = (uint32_t*)((char*)(fHeader) + sect->offset() + sreloc->r_address());
+               instruction = LittleEndian::get32(*fixUpPtr);
+               
+               // A ARM_RELOC_PAIR only follows ARM_RELOC_{SECTDIFF,LOCAL_SECTDIFF}
+               // relocation types, and it is an error to see one otherwise.
+               bool nextRelocIsPair = false;
+               uint32_t nextRelocAddress = 0;
+               uint32_t nextRelocValue = 0;
+               if ( nextSReloc->r_type() == ARM_RELOC_PAIR ) {
+                       nextRelocIsPair = true;
+                       nextRelocAddress = nextSReloc->r_address();
+                       nextRelocValue = nextSReloc->r_value();
+                       result = true;
+               }
+               
+               switch (sreloc->r_type()) {
+                       case ARM_RELOC_VANILLA:
+                               if ( sreloc->r_length() != 2 )
+                                       throw "bad length for ARM_RELOC_VANILLA";
+
+                               betterDstAddr = LittleEndian::get32(*fixUpPtr);
+                               //fprintf(stderr, "scattered pointer reloc: srcAddr=0x%08X, dstAddr=0x%08X, pointer=0x%08X\n", srcAddr, dstAddr, betterDstAddr);
+                               // with a scattered relocation we get both the target (sreloc->r_value()) and the target+offset (*fixUpPtr)
+                               makeReferenceWithToBase(arm::kPointer, srcAddr, betterDstAddr, dstAddr);
+                               break;
+               
+                       case ARM_RELOC_BR24:
+                               // Sign-extend displacement
+                               displacement = (instruction & 0x00FFFFFF) << 2;
+                               if ( (displacement & 0x02000000) != 0 )
+                                       displacement |= 0xFC000000;
+                               // The pc added will be +8 from the pc
+                               displacement += 8;
+                               // If this is BLX add H << 1
+                               if ((instruction & 0xFE000000) == 0xFA000000)
+                                       displacement += ((instruction & 0x01000000) >> 23);
+                               betterDstAddr = srcAddr+displacement;
+                               makeReferenceWithToBase(arm::kBranch24, srcAddr, betterDstAddr, dstAddr);
+                               break;
+               
+                       case ARM_THUMB_RELOC_BR22:
+                               // First instruction has upper 11 bits of the displacement.
+                               displacement = (instruction & 0x7FF) << 12;
+                               if ( (displacement & 0x400000) != 0 )
+                                       displacement |= 0xFF800000;
+                               // Second instruction has lower eleven bits of the displacement.
+                               displacement += ((instruction >> 16) & 0x7FF) << 1;
+                               // The pc added will be +4 from the pc
+                               displacement += 4;
+                               betterDstAddr = srcAddr+displacement;
+                               // If the instruction was blx, force the low 2 bits to be clear
+                               if ((instruction & 0xF8000000) == 0xE8000000)
+                                       betterDstAddr &= 0xFFFFFFFC;
+                               makeReferenceWithToBase(arm::kThumbBranch22, srcAddr, betterDstAddr, dstAddr);
+                               break;
+               
+                       case ARM_RELOC_SECTDIFF:
+                       case ARM_RELOC_LOCAL_SECTDIFF:
+                               if ( !nextRelocIsPair ) {
+                                       warning("ARM_RELOC_SECTDIFF missing following pair");
+                                       break;
+                               }
+                               if ( sreloc->r_length() != 2 )
+                                       throw "bad length for ARM_RELOC_SECTDIFF";
+                               {
+                               AtomAndOffset srcao  = findAtomAndOffset(srcAddr);
+                               AtomAndOffset fromao = findAtomAndOffset(nextRelocValue);
+                               AtomAndOffset toao   = findAtomAndOffset(dstAddr);
+                               // check for addend encoded in the section content
+                               pointerValue = LittleEndian::get32(*fixUpPtr);
+                               if ( (dstAddr - nextRelocValue) != pointerValue ) {
+                                       if ( toao.atom == srcao.atom )
+                                               toao.offset += (pointerValue + nextRelocValue) - dstAddr;
+                                       else if ( fromao.atom == srcao.atom )
+                                               toao.offset += (pointerValue + nextRelocValue) - dstAddr;
+                                       else
+                                               fromao.offset += (dstAddr - pointerValue) - nextRelocValue;
+                               }
+                               new Reference<arm>(arm::kPointerDiff, srcao, fromao, toao);
+                               }
+                               break;
+                       
+                       default:
+                               warning("unexpected srelocation type %u", sreloc->r_type());
+                               break;
+               }
+       }
+       return result;
+}
+
 template <typename A>
 void Reader<A>::addReferencesForSection(const macho_section<P>* sect)
 {
@@ -3629,7 +4075,7 @@ void Reader<A>::addReferencesForSection(const macho_section<P>* sect)
                                                        ++r; // skip next
                                        }
                                        catch (const char* msg) {
-                                               throwf("in section %s,%s reloc %u: %s\n", sect->segname(), sect->sectname(), r, msg);
+                                               throwf("in section %s,%s reloc %u: %s", sect->segname(), sect->sectname(), r, msg);
                                        }
                                }
                }
@@ -3648,6 +4094,9 @@ const char* Reference<x86>::getDescription() const
                case x86::kFollowOn:
                        sprintf(temp, "followed by ");
                        break;
+               case x86::kGroupSubordinate:
+                       sprintf(temp, "group subordinate ");
+                       break;
                case x86::kPointerWeakImport:
                        sprintf(temp, "offset 0x%04X, weak import pointer to ", fFixUpOffsetInSrc);
                        break;
@@ -3685,6 +4134,9 @@ const char* Reference<x86>::getDescription() const
                case x86::kPCRel16:
                        sprintf(temp, "offset 0x%04X, rel16 reference to ", fFixUpOffsetInSrc);
                        break;
+               case x86::kPCRel8:
+                       sprintf(temp, "offset 0x%04X, rel8 reference to ", fFixUpOffsetInSrc);
+                       break;
                case x86::kAbsolute32:
                        sprintf(temp, "offset 0x%04X, absolute32 reference to ", fFixUpOffsetInSrc);
                        break;
@@ -3731,6 +4183,9 @@ const char* Reference<ppc>::getDescription() const
                case ppc::kFollowOn:
                        sprintf(temp, "followed by ");
                        break;
+               case ppc::kGroupSubordinate:
+                       sprintf(temp, "group subordinate ");
+                       break;
                case ppc::kPointerWeakImport:
                        sprintf(temp, "offset 0x%04X, weak import pointer to ", fFixUpOffsetInSrc);
                        break;
@@ -3830,6 +4285,9 @@ const char* Reference<ppc64>::getDescription() const
                case ppc64::kFollowOn:
                        sprintf(temp, "followed by ");
                        break;
+               case ppc64::kGroupSubordinate:
+                       sprintf(temp, "group subordinate ");
+                       break;
                case ppc64::kPointerWeakImport:
                        sprintf(temp, "offset 0x%04llX, weak import pointer to ", fFixUpOffsetInSrc);
                        break;
@@ -3937,6 +4395,9 @@ const char* Reference<x86_64>::getDescription() const
                case x86_64::kFollowOn:
                        sprintf(temp, "followed by ");
                        break;
+               case x86_64::kGroupSubordinate:
+                       sprintf(temp, "group subordinate ");
+                       break;
                case x86_64::kPointerWeakImport:
                        sprintf(temp, "offset 0x%04llX, weak import pointer to ", fFixUpOffsetInSrc);
                        break;
@@ -3986,6 +4447,9 @@ const char* Reference<x86_64>::getDescription() const
                case x86_64::kPCRel32GOTLoadWeakImport:
                        sprintf(temp, "offset 0x%04llX, rel32 reference to GOT entry for weak imported ", fFixUpOffsetInSrc);
                        break;
+               case x86_64::kBranchPCRel8:
+                       sprintf(temp, "offset 0x%04llX, branch rel8 reference to ", fFixUpOffsetInSrc);
+                       break;
                case x86_64::kDtraceProbe:
                        sprintf(temp, "offset 0x%04llX, dtrace static probe ", fFixUpOffsetInSrc);
                        break;
@@ -4017,7 +4481,74 @@ const char* Reference<x86_64>::getDescription() const
        return temp;
 }
 
+template <>
+const char* Reference<arm>::getDescription() const
+{
+       static char temp[2048];
+       switch( fKind ) {
+               case arm::kNoFixUp:
+                       sprintf(temp, "reference to ");
+                       break;
+               case arm::kFollowOn:
+                       sprintf(temp, "followed by ");
+                       break;
+               case arm::kGroupSubordinate:
+                       sprintf(temp, "group subordinate ");
+                       break;
+               case arm::kPointer:
+                       sprintf(temp, "offset 0x%04X, pointer to ", fFixUpOffsetInSrc);
+                       break;
+               case arm::kPointerWeakImport:
+                       sprintf(temp, "offset 0x%04X, weak import pointer to ", fFixUpOffsetInSrc);
+                       break;
+               case arm::kPointerDiff:
+                       {
+                       // by-name references have quoted names
+                       const char* targetQuotes = (&(this->getTarget()) == NULL) ? "\"" : "";
+                       const char* fromQuotes = (&(this->getFromTarget()) == NULL) ? "\"" : "";
+                       sprintf(temp, "offset 0x%04X, 32-bit pointer difference: (&%s%s%s + %d) - (&%s%s%s + %d)",
+                               fFixUpOffsetInSrc, targetQuotes, this->getTargetName(), targetQuotes, fToTarget.offset,
+                                                          fromQuotes, this->getFromTargetName(), fromQuotes, fFromTarget.offset );
+                       return temp;
+                       }
+               case arm::kBranch24:
+        case arm::kThumbBranch22:
+                       sprintf(temp, "offset 0x%04X, pc-rel branch fixup to ", fFixUpOffsetInSrc);
+                       break;
+               case arm::kBranch24WeakImport:
+        case arm::kThumbBranch22WeakImport:
+                       sprintf(temp, "offset 0x%04X, pc-rel branch fixup to weak imported ", fFixUpOffsetInSrc);
+                       break;
+               case arm::kDtraceProbe:
+                       sprintf(temp, "offset 0x%04X, dtrace static probe ", fFixUpOffsetInSrc);
+                       break;
+               case arm::kDtraceProbeSite:
+                       sprintf(temp, "offset 0x%04X, dtrace static probe site", fFixUpOffsetInSrc);
+                       break;
+               case arm::kDtraceIsEnabledSite:
+                       sprintf(temp, "offset 0x%04X, dtrace static probe is-enabled site", fFixUpOffsetInSrc);
+                       break;
+               case arm::kDtraceTypeReference:
+                       sprintf(temp, "offset 0x%04X, dtrace type/stability reference", fFixUpOffsetInSrc);
+                       break;
+       }
+       // always quote by-name references
+       if ( fToTargetName != NULL ) {
+               strcat(temp, "\"");
+               strcat(temp, fToTargetName);
+               strcat(temp, "\"");
+       }
+       else if ( fToTarget.atom != NULL ) {
+               strcat(temp, fToTarget.atom->getDisplayName());
+       }
+       else {
+               strcat(temp, "NULL target");
+       }
+       if ( fToTarget.offset != 0 )
+               sprintf(&temp[strlen(temp)], " plus 0x%08X", fToTarget.offset);
 
+       return temp;
+}
 
 }; // namespace relocatable
 }; // namespace mach_o
old mode 100644 (file)
new mode 100755 (executable)
index 56c6dd2..3c9f792
@@ -1,6 +1,6 @@
 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
  *
- * Copyright (c) 2005-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2005-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 #include <stddef.h>
 #include <fcntl.h>
 #include <sys/time.h>
-#include <mach-o/loader.h>
-#include <mach-o/nlist.h>
-#include <mach-o/reloc.h>
-//#include <mach-o/ppc/reloc.h>
-#include <mach-o/stab.h>
 #include <uuid/uuid.h>
 #include <mach/i386/thread_status.h>
 #include <mach/ppc/thread_status.h>
 
 #include "MachOFileAbstraction.hpp"
 
-#ifndef S_DTRACE_DOF
-  #define S_DTRACE_DOF 0xF
-#endif
-
-#ifndef MH_PIE
-       #define MH_PIE 0x200000 
-#endif
 
 //
 //
@@ -83,6 +71,7 @@ template <typename A> class PageZeroAtom;
 template <typename A> class CustomStackAtom;
 template <typename A> class MachHeaderAtom;
 template <typename A> class SegmentLoadCommandsAtom;
+template <typename A> class EncryptionLoadCommandsAtom;
 template <typename A> class SymbolTableLoadCommandsAtom;
 template <typename A> class ThreadsLoadCommandsAtom;
 template <typename A> class DylibIDLoadCommandsAtom;
@@ -110,9 +99,11 @@ template <typename A> class DylibLoadCommandsAtom;
 // SectionInfo should be nested inside Writer, but I can't figure out how to make the type accessible to the Atom classes
 class SectionInfo : public ObjectFile::Section {
 public:
-                                                                               SectionInfo() : fFileOffset(0), fSize(0), fRelocCount(0), fRelocOffset(0), fIndirectSymbolOffset(0),
-                                                                                                               fAlignment(0), fAllLazyPointers(false), fAllNonLazyPointers(false), fAllStubs(false),
-                                                                                                               fAllSelfModifyingStubs(false), fAllZeroFill(false), fVirtualSection(false)
+                                                                               SectionInfo() : fFileOffset(0), fSize(0), fRelocCount(0), fRelocOffset(0), 
+                                                                                                               fIndirectSymbolOffset(0), fAlignment(0), fAllLazyPointers(false), 
+                                                                                                               fAllLazyDylibPointers(false),fAllNonLazyPointers(false), fAllStubs(false),
+                                                                                                               fAllSelfModifyingStubs(false), fAllZeroFill(false), fVirtualSection(false),
+                                                                                                               fHasTextLocalRelocs(false), fHasTextExternalRelocs(false)
                                                                                                                { fSegmentName[0] = '\0'; fSectionName[0] = '\0'; }
        void                                                            setIndex(unsigned int index) { fIndex=index; }
        std::vector<ObjectFile::Atom*>          fAtoms;
@@ -125,11 +116,14 @@ public:
        uint32_t                                                        fIndirectSymbolOffset;
        uint8_t                                                         fAlignment;
        bool                                                            fAllLazyPointers;
+       bool                                                            fAllLazyDylibPointers;
        bool                                                            fAllNonLazyPointers;
        bool                                                            fAllStubs;
        bool                                                            fAllSelfModifyingStubs;
        bool                                                            fAllZeroFill;
        bool                                                            fVirtualSection;
+       bool                                                            fHasTextLocalRelocs;
+       bool                                                            fHasTextExternalRelocs;
 };
 
 // SegmentInfo should be nested inside Writer, but I can't figure out how to make the type accessible to the Atom classes
@@ -172,9 +166,10 @@ public:
                                                                                                                  std::vector<class ObjectFile::Reader::Stab>& stabs,
                                                                                                                  class ObjectFile::Atom* entryPointAtom,
                                                                                                                  class ObjectFile::Atom* dyldHelperAtom,
+                                                                                                                 class ObjectFile::Atom* dyldLazyDylibHelperAtom,
                                                                                                                  bool createUUID, bool canScatter,
                                                                                                                  ObjectFile::Reader::CpuConstraint cpuConstraint,
-                                                                                                                 bool biggerThanTwoGigs);
+                                                                                                                 bool biggerThanTwoGigs, bool overridesDylibWeakDefines);
 
 private:
        typedef typename A::P                   P;
@@ -196,7 +191,7 @@ private:
        const char*                                     getArchString();
        void                                            writeMap();
        uint64_t                                        writeAtoms();
-       void                                            writeNoOps(uint32_t from, uint32_t to);
+       void                                            writeNoOps(int fd, uint32_t from, uint32_t to);
        void                                            copyNoOps(uint8_t* from, uint8_t* to);
        bool                                            segmentsCanSplitApart(const ObjectFile::Atom& from, const ObjectFile::Atom& to);
        void                                            addCrossSegmentRef(const ObjectFile::Atom* atom, const ObjectFile::Reference* ref);
@@ -229,7 +224,7 @@ private:
        uint32_t                                        addObjectRelocs_powerpc(ObjectFile::Atom* atom, ObjectFile::Reference* ref);
        uint8_t                                         getRelocPointerSize();
        uint64_t                                        maxAddress();
-       bool                                            stubableReference(const ObjectFile::Reference* ref);
+       bool                                            stubableReference(const ObjectFile::Atom* inAtom, const ObjectFile::Reference* ref);
        bool                                            GOTReferenceKind(uint8_t kind);
        bool                                            optimizableGOTReferenceKind(uint8_t kind);
        bool                                            weakImportReferenceKind(uint8_t kind);
@@ -240,6 +235,8 @@ private:
        void                                            addStabs(uint32_t startIndex);
        RelocKind                                       relocationNeededInFinalLinkedImage(const ObjectFile::Atom& target) const;
        bool                                            illegalRelocInFinalLinkedImage(const ObjectFile::Reference&);
+       bool                                            generatesLocalTextReloc(const ObjectFile::Reference&, const ObjectFile::Atom& atom, SectionInfo* curSection);
+       bool                                            generatesExternalTextReloc(const ObjectFile::Reference&, const ObjectFile::Atom& atom, SectionInfo* curSection);
        bool                                            mightNeedPadSegment();
        void                                            scanForAbsoluteReferences();
        bool                                            needsModuleTable();
@@ -257,6 +254,7 @@ private:
        friend class CustomStackAtom<A>;
        friend class MachHeaderAtom<A>;
        friend class SegmentLoadCommandsAtom<A>;
+       friend class EncryptionLoadCommandsAtom<A>;
        friend class SymbolTableLoadCommandsAtom<A>;
        friend class ThreadsLoadCommandsAtom<A>;
        friend class DylibIDLoadCommandsAtom<A>;
@@ -282,11 +280,11 @@ private:
 
        const char*                                                                             fFilePath;
        Options&                                                                                fOptions;
-       int                                                                                             fFileDescriptor;
        std::vector<class ObjectFile::Atom*>*                   fAllAtoms;
        std::vector<class ObjectFile::Reader::Stab>*    fStabs;
        class SectionInfo*                                                              fLoadCommandsSection;
        class SegmentInfo*                                                              fLoadCommandsSegment;
+       class EncryptionLoadCommandsAtom<A>*                    fEncryptionLoadCommand;
        class SegmentLoadCommandsAtom<A>*                               fSegmentCommands;
        class SymbolTableLoadCommandsAtom<A>*                   fSymbolTableCommands;
        class LoadCommandsPaddingAtom<A>*                               fHeaderPadding;
@@ -296,6 +294,7 @@ private:
        class SegmentInfo*                                                              fPadSegmentInfo;
        class ObjectFile::Atom*                                                 fEntryPoint;
        class ObjectFile::Atom*                                                 fDyldHelper;
+       class ObjectFile::Atom*                                                 fDyldLazyDylibHelper;
        std::map<class ObjectFile::Reader*, DylibLoadCommandsAtom<A>*>  fLibraryToLoadCommand;
        std::map<class ObjectFile::Reader*, uint32_t>   fLibraryToOrdinal;
        std::map<class ObjectFile::Reader*, class ObjectFile::Reader*>  fLibraryAliases;
@@ -322,6 +321,7 @@ private:
        std::vector<class StubAtom<A>*>                                 fAllSynthesizedStubs;
        std::vector<ObjectFile::Atom*>                                  fAllSynthesizedStubHelpers;
        std::vector<class LazyPointerAtom<A>*>                  fAllSynthesizedLazyPointers;
+       std::vector<class LazyPointerAtom<A>*>                  fAllSynthesizedLazyDylibPointers;
        std::vector<class NonLazyPointerAtom<A>*>               fAllSynthesizedNonLazyPointers;
        uint32_t                                                                                fSymbolTableCount;
        uint32_t                                                                                fSymbolTableStabsCount;
@@ -342,6 +342,8 @@ private:
        bool                                                                                    fBiggerThanTwoGigs;
        bool                                                                                    fSlideable;
        std::map<const ObjectFile::Atom*,bool>                  fWeakImportMap;
+       std::set<const ObjectFile::Reader*>                             fDylibReadersWithNonWeakImports;
+       std::set<const ObjectFile::Reader*>                             fDylibReadersWithWeakImports;
        SegmentInfo*                                                                    fFirstWritableSegment;
        ObjectFile::Reader::CpuConstraint                               fCpuConstraint;
        uint32_t                                                                                fAnonNameIndex;
@@ -403,6 +405,7 @@ public:
        virtual SymbolTableInclusion                    getSymbolTableInclusion() const { return ObjectFile::Atom::kSymbolTableNotIn; }
        virtual bool                                                    dontDeadStrip() const                   { return true; }
        virtual bool                                                    isZeroFill() const                              { return false; }
+       virtual bool                                                    isThumb() const                                 { return false; }
        virtual std::vector<ObjectFile::Reference*>&  getReferences() const             { return fgEmptyReferenceList; }
        virtual bool                                                    mustRemainInSection() const             { return true; }
        virtual ObjectFile::Segment&                    getSegment() const                              { return fSegment; }
@@ -507,7 +510,7 @@ protected:
        virtual const char*                                             getSectionName() const  { return "._load_commands"; }
        virtual uint32_t                                                getOrdinal() const              { return fOrdinal; }
        static uint64_t                                                 alignedSize(uint64_t size);
-private:
+protected:
        uint32_t                                                                fOrdinal;
        static uint32_t                                                 fgCurrentOrdinal;
 };
@@ -616,11 +619,13 @@ class DylibLoadCommandsAtom : public LoadCommandAtom<A>
 {
 public:
                                                                                        DylibLoadCommandsAtom(Writer<A>& writer, ExecutableFile::DyLibUsed& info) 
-                                                                                        : LoadCommandAtom<A>(writer, Segment::fgTextSegment), fInfo(info), fOptimizedAway(false) {}
+                                                                                        : LoadCommandAtom<A>(writer, Segment::fgTextSegment), fInfo(info), 
+                                                                                               fOptimizedAway(false) { if (fInfo.options.fLazyLoad) this->fOrdinal += 256; }
        virtual const char*                                             getDisplayName() const  { return "dylib load command"; }
        virtual uint64_t                                                getSize() const;
        virtual void                                                    copyRawContent(uint8_t buffer[]) const;
        virtual void                                                    optimizeAway() { fOptimizedAway = true; }
+                       bool                                                    linkedWeak() { return fInfo.options.fWeakImport; }
 private:
        using WriterAtom<A>::fWriter;
        typedef typename A::P                                   P;
@@ -734,6 +739,24 @@ private:
        const char*                                                             fPath;
 };
 
+template <typename A>
+class EncryptionLoadCommandsAtom : public LoadCommandAtom<A>
+{
+public:
+                                                                                       EncryptionLoadCommandsAtom(Writer<A>& writer)
+                                                                                               : LoadCommandAtom<A>(writer, Segment::fgTextSegment), fStartOffset(0),
+                                                                                                 fEndOffset(0) {}
+       virtual const char*                                             getDisplayName() const  { return "encryption info load command"; }
+       virtual uint64_t                                                getSize() const { return sizeof(macho_encryption_info_command<typename A::P>); }
+       virtual void                                                    copyRawContent(uint8_t buffer[]) const;
+       void                                                                    setStartEncryptionOffset(uint32_t off) { fStartOffset = off; }
+       void                                                                    setEndEncryptionOffset(uint32_t off) { fEndOffset = off; }
+private:
+       using WriterAtom<A>::fWriter;
+       typedef typename A::P                                   P;
+       uint32_t                                                                fStartOffset;
+       uint32_t                                                                fEndOffset;
+};
 
 template <typename A>
 class LoadCommandsPaddingAtom : public WriterAtom<A>
@@ -890,7 +913,7 @@ class ModuleInfoLinkEditAtom : public LinkEditAtom<A>
 {
 public:
                                                                                        ModuleInfoLinkEditAtom(Writer<A>& writer) : LinkEditAtom<A>(writer), fModuleNameOffset(0) { }
-       virtual const char*                                             getDisplayName() const  { return "modulel table"; }
+       virtual const char*                                             getDisplayName() const  { return "module table"; }
        virtual uint64_t                                                getSize() const;
        virtual const char*                                             getSectionName() const  { return "._module_info"; }
        virtual void                                                    copyRawContent(uint8_t buffer[]) const;
@@ -981,7 +1004,7 @@ template <typename A>
 class StubAtom : public WriterAtom<A>
 {
 public:
-                                                                                       StubAtom(Writer<A>& writer, ObjectFile::Atom& target);
+                                                                                       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 uint64_t                                                getSize() const;
@@ -992,18 +1015,19 @@ public:
        ObjectFile::Atom*                                               getTarget()                                     { return &fTarget; }
 private:
        static const char*                                              stubName(const char* importName);
-       bool                                                                    pic() const;
+       bool                                                                    pic() const                                     { return fWriter.fSlideable; }
        using WriterAtom<A>::fWriter;
        const char*                                                             fName;
        ObjectFile::Atom&                                               fTarget;
        std::vector<ObjectFile::Reference*>             fReferences;
+       bool                                                                    fForLazyDylib;
 };
 
 template <typename A>
 class StubHelperAtom : public WriterAtom<A>
 {
 public:
-                                                                                       StubHelperAtom(Writer<A>& writer, ObjectFile::Atom& target, ObjectFile::Atom& lazyPointer);
+                                                                                       StubHelperAtom(Writer<A>& writer, ObjectFile::Atom& target, ObjectFile::Atom& lazyPointer, bool forLazyDylib);
        virtual const char*                                             getName() const                         { return fName; }
        virtual ObjectFile::Atom::Scope                 getScope() const                        { return ObjectFile::Atom::scopeLinkageUnit; }
        virtual uint64_t                                                getSize() const;
@@ -1023,20 +1047,23 @@ template <typename A>
 class LazyPointerAtom : public WriterAtom<A>
 {
 public:
-                                                                                       LazyPointerAtom(Writer<A>& writer, ObjectFile::Atom& target);
+                                                                                       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 uint64_t                                                getSize() const                         { return sizeof(typename A::P::uint_t); }
-       virtual const char*                                             getSectionName() const          { return "__la_symbol_ptr"; }
+       virtual const char*                                             getSectionName() const          { return fForLazyDylib ? "__ld_symbol_ptr" : "__la_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; }
+       ObjectFile::Atom*                                               getTarget()                                     { return &fExternalTarget; }
 private:
        using WriterAtom<A>::fWriter;
        static const char*                                              lazyPointerName(const char* importName);
        const char*                                                             fName;
        ObjectFile::Atom&                                               fTarget;
+       ObjectFile::Atom&                                               fExternalTarget;
        std::vector<ObjectFile::Reference*>             fReferences;
+       bool                                                                    fForLazyDylib;
 };
 
 
@@ -1119,15 +1146,23 @@ private:
 
 
 template <>
-StubHelperAtom<x86_64>::StubHelperAtom(Writer<x86_64>& writer, ObjectFile::Atom& target, ObjectFile::Atom& lazyPointer)
+StubHelperAtom<x86_64>::StubHelperAtom(Writer<x86_64>& writer, ObjectFile::Atom& target, 
+                                                                                                                       ObjectFile::Atom& lazyPointer, bool forLazyDylib)
  : WriterAtom<x86_64>(writer, Segment::fgTextSegment), fName(stubName(target.getName())), fTarget(target)
 {
        writer.fAllSynthesizedStubHelpers.push_back(this);
 
        fReferences.push_back(new WriterReference<x86_64>(3, x86_64::kPCRel32, &lazyPointer));
-       fReferences.push_back(new WriterReference<x86_64>(8, x86_64::kPCRel32, writer.fDyldHelper));
-       if ( writer.fDyldHelper == NULL )
-               throw "symbol dyld_stub_binding_helper not defined (usually in crt1.o/dylib1.o/bundle1.o)";
+       if ( forLazyDylib ) {
+               if ( writer.fDyldLazyDylibHelper == NULL )
+                       throw "symbol dyld_lazy_dylib_stub_binding_helper not defined (usually in crt1.o/dylib1.o/bundle1.o)";
+               fReferences.push_back(new WriterReference<x86_64>(8, x86_64::kPCRel32, writer.fDyldLazyDylibHelper));
+       }
+       else {
+               if ( writer.fDyldHelper == NULL )
+                       throw "symbol dyld_stub_binding_helper not defined (usually in crt1.o/dylib1.o/bundle1.o)";
+               fReferences.push_back(new WriterReference<x86_64>(8, x86_64::kPCRel32, writer.fDyldHelper));
+       }
 }
 
 template <>
@@ -1153,6 +1188,7 @@ void StubHelperAtom<x86_64>::copyRawContent(uint8_t buffer[]) const
        buffer[11] = 0x00;
 }
 
+
 template <typename A>
 const char* StubHelperAtom<A>::stubName(const char* name)
 {
@@ -1164,21 +1200,43 @@ const char* StubHelperAtom<A>::stubName(const char* name)
 
 // specialize lazy pointer for x86_64 to initially pointer to stub helper
 template <>
-LazyPointerAtom<x86_64>::LazyPointerAtom(Writer<x86_64>& writer, ObjectFile::Atom& target)
- : WriterAtom<x86_64>(writer, Segment::fgDataSegment), fName(lazyPointerName(target.getName())), fTarget(target)
+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)
 {
-       writer.fAllSynthesizedLazyPointers.push_back(this);
+       if ( forLazyDylib ) 
+               writer.fAllSynthesizedLazyDylibPointers.push_back(this);
+       else
+               writer.fAllSynthesizedLazyPointers.push_back(this);
 
-       StubHelperAtom<x86_64>* helper = new StubHelperAtom<x86_64>(writer, target, *this);
+       StubHelperAtom<x86_64>* helper = new StubHelperAtom<x86_64>(writer, target, *this, forLazyDylib);
        fReferences.push_back(new WriterReference<x86_64>(0, x86_64::kPointer, helper));
 }
 
+// specialize lazy pointer for x86 to initially pointer to second half of stub
+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)
+{
+       if ( forLazyDylib ) 
+               writer.fAllSynthesizedLazyDylibPointers.push_back(this);
+       else
+               writer.fAllSynthesizedLazyPointers.push_back(this);
+
+       // helper part of stub is 14 or 6 bytes into stub
+       fReferences.push_back(new WriterReference<x86>(0, x86::kPointer, &stub, writer.fSlideable ? 14 : 6));
+}
 
 template <typename A>
-LazyPointerAtom<A>::LazyPointerAtom(Writer<A>& writer, ObjectFile::Atom& target)
- : WriterAtom<A>(writer, Segment::fgDataSegment), fName(lazyPointerName(target.getName())), fTarget(target)
+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)
 {
-       writer.fAllSynthesizedLazyPointers.push_back(this);
+       if ( forLazyDylib ) 
+               writer.fAllSynthesizedLazyDylibPointers.push_back(this);
+       else
+               writer.fAllSynthesizedLazyPointers.push_back(this);
 
        fReferences.push_back(new WriterReference<A>(0, A::kPointer, &target));
 }
@@ -1233,8 +1291,9 @@ bool StubAtom<ppc64>::pic() const
        return ( fWriter.fSlideable || ((fWriter.fPageZeroAtom != NULL) && (fWriter.fPageZeroAtom->getSize() > 4096)) );
 }
 
+
 template <>
-bool StubAtom<ppc>::pic() const
+bool StubAtom<arm>::pic() const
 {
        return fWriter.fSlideable;
 }
@@ -1252,12 +1311,36 @@ ObjectFile::Alignment StubAtom<ppc64>::getAlignment() const
 }
 
 template <>
-StubAtom<ppc>::StubAtom(Writer<ppc>& writer, ObjectFile::Atom& target)
- : WriterAtom<ppc>(writer, Segment::fgTextSegment), fName(stubName(target.getName())), fTarget(target)
+ObjectFile::Alignment StubAtom<arm>::getAlignment() const
 {
-       writer.fAllSynthesizedStubs.push_back(this);
+       return 2;
+}
 
-       LazyPointerAtom<ppc>* lp = new LazyPointerAtom<ppc>(writer, target);
+template <>
+StubAtom<ppc>::StubAtom(Writer<ppc>& writer, ObjectFile::Atom& target, bool forLazyDylib)
+ : WriterAtom<ppc>(writer, Segment::fgTextSegment), fName(stubName(target.getName())), 
+       fTarget(target), fForLazyDylib(forLazyDylib)
+{
+       writer.fAllSynthesizedStubs.push_back(this);
+       LazyPointerAtom<ppc>* lp;
+       if (  fWriter.fOptions.prebind() ) {
+               // for prebound ppc, 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<ppc>(writer, target, *this, forLazyDylib);
+       }
+       else {
+               // for non-prebound ppc, lazy pointer starts out pointing to dyld_stub_binding_helper glue code
+               if ( forLazyDylib ) {
+                       if ( writer.fDyldLazyDylibHelper == NULL )
+                               throw "symbol dyld_lazy_dylib_stub_binding_helper not defined (usually in crt1.o/dylib1.o/bundle1.o)";
+                       lp = new LazyPointerAtom<ppc>(writer, *writer.fDyldLazyDylibHelper, *this, forLazyDylib);
+               }
+               else {
+                       if ( writer.fDyldHelper == NULL )
+                               throw "symbol dyld_stub_binding_helper not defined (usually in crt1.o/dylib1.o/bundle1.o)";
+                       lp = new LazyPointerAtom<ppc>(writer, *writer.fDyldHelper, *this, forLazyDylib);
+               }
+       }
        if ( pic() ) {
                // picbase is 8 bytes into atom
                fReferences.push_back(new WriterReference<ppc>(12, ppc::kPICBaseHigh16, lp, 0, this, 8));
@@ -1270,12 +1353,23 @@ StubAtom<ppc>::StubAtom(Writer<ppc>& writer, ObjectFile::Atom& target)
 }
 
 template <>
-StubAtom<ppc64>::StubAtom(Writer<ppc64>& writer, ObjectFile::Atom& target)
- : WriterAtom<ppc64>(writer, Segment::fgTextSegment), fName(stubName(target.getName())), fTarget(target)
+StubAtom<ppc64>::StubAtom(Writer<ppc64>& writer, ObjectFile::Atom& target, bool forLazyDylib)
+ : WriterAtom<ppc64>(writer, Segment::fgTextSegment), fName(stubName(target.getName())), 
+       fTarget(target), fForLazyDylib(forLazyDylib)
 {
        writer.fAllSynthesizedStubs.push_back(this);
 
-       LazyPointerAtom<ppc64>* lp = new LazyPointerAtom<ppc64>(writer, target);
+       LazyPointerAtom<ppc64>* lp;
+       if ( forLazyDylib ) {
+               if ( writer.fDyldLazyDylibHelper == NULL )
+                       throw "symbol dyld_lazy_dylib_stub_binding_helper not defined (usually in crt1.o/dylib1.o/bundle1.o)";
+               lp = new LazyPointerAtom<ppc64>(writer, *writer.fDyldLazyDylibHelper, *this, forLazyDylib);
+       }
+       else {
+               if ( writer.fDyldHelper == NULL )
+                       throw "symbol dyld_stub_binding_helper not defined (usually in crt1.o/dylib1.o/bundle1.o)";
+               lp = new LazyPointerAtom<ppc64>(writer, *writer.fDyldHelper, *this, forLazyDylib);
+       }
        if ( pic() ) {
                // picbase is 8 bytes into atom
                fReferences.push_back(new WriterReference<ppc64>(12, ppc64::kPICBaseHigh16, lp, 0, this, 8));
@@ -1289,28 +1383,81 @@ StubAtom<ppc64>::StubAtom(Writer<ppc64>& writer, ObjectFile::Atom& target)
 
 // specialize to put x86 fast stub in __IMPORT segment with no lazy pointer
 template <>
-StubAtom<x86>::StubAtom(Writer<x86>& writer, ObjectFile::Atom& target)
- : WriterAtom<x86>(writer, writer.fOptions.readOnlyx86Stubs() ? Segment::fgROImportSegment : Segment::fgImportSegment), 
-                               fTarget(target)
+StubAtom<x86>::StubAtom(Writer<x86>& writer, ObjectFile::Atom& target, bool forLazyDylib)
+ : WriterAtom<x86>(writer, (writer.fOptions.slowx86Stubs() || forLazyDylib) ? Segment::fgTextSegment : 
+                                       ( writer.fOptions.readOnlyx86Stubs() ? Segment::fgROImportSegment : Segment::fgImportSegment)), 
+                               fTarget(target), fForLazyDylib(forLazyDylib)
 {
-       if ( &target == NULL )
-               fName = "cache-line-crossing-stub";
-       else {
+       if ( writer.fOptions.slowx86Stubs() || forLazyDylib ) {
                fName = stubName(target.getName());
                writer.fAllSynthesizedStubs.push_back(this);
+               LazyPointerAtom<x86>* lp = new LazyPointerAtom<x86>(writer, target, *this, forLazyDylib);
+               ObjectFile::Atom* helper;
+               if ( forLazyDylib ) {
+                       if ( writer.fDyldLazyDylibHelper == NULL )
+                               throw "symbol dyld_lazy_dylib_stub_binding_helper not defined (usually in crt1.o/dylib1.o/bundle1.o)";
+                       helper = writer.fDyldLazyDylibHelper;
+               }
+               else {
+                       if ( writer.fDyldHelper == NULL )
+                               throw "symbol dyld_stub_binding_helper not defined (usually in crt1.o/dylib1.o/bundle1.o)";
+                       helper = writer.fDyldHelper;
+               }
+               if ( pic() ) {
+                       // picbase is 5 bytes into atom
+                       fReferences.push_back(new WriterReference<x86>(8, x86::kPointerDiff, lp, 0, this, 5));
+                       fReferences.push_back(new WriterReference<x86>(16, x86::kPCRel32, helper));
+               }
+               else {
+                       fReferences.push_back(new WriterReference<x86>(2, x86::kAbsolute32, lp));
+                       fReferences.push_back(new WriterReference<x86>(7, x86::kAbsolute32, lp));
+                       fReferences.push_back(new WriterReference<x86>(12, x86::kPCRel32, helper));
+               }
+       }
+       else {
+               if ( &target == NULL ) 
+                       fName = "cache-line-crossing-stub";
+               else {
+                       fName = stubName(target.getName());
+                       writer.fAllSynthesizedStubs.push_back(this);
+               }
        }
 }
 
 template <>
-StubAtom<x86_64>::StubAtom(Writer<x86_64>& writer, ObjectFile::Atom& target)
+StubAtom<x86_64>::StubAtom(Writer<x86_64>& writer, ObjectFile::Atom& target, bool forLazyDylib)
  : WriterAtom<x86_64>(writer, Segment::fgTextSegment), fName(stubName(target.getName())), fTarget(target)
 {
        writer.fAllSynthesizedStubs.push_back(this);
 
-       LazyPointerAtom<x86_64>* lp = new LazyPointerAtom<x86_64>(writer, target);
+       LazyPointerAtom<x86_64>* lp = new LazyPointerAtom<x86_64>(writer, target, *this, forLazyDylib);
        fReferences.push_back(new WriterReference<x86_64>(2, x86_64::kPCRel32, lp));
 }
 
+template <>
+StubAtom<arm>::StubAtom(Writer<arm>& writer, ObjectFile::Atom& target, bool forLazyDylib)
+ : WriterAtom<arm>(writer, Segment::fgTextSegment), fName(stubName(target.getName())), fTarget(target)
+{
+       writer.fAllSynthesizedStubs.push_back(this);
+
+       LazyPointerAtom<arm>* lp;
+       if (  fWriter.fOptions.prebind() ) {
+               // 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);
+       }
+       else {
+               // for non-prebound arm, lazy pointer starts out pointing to dyld_stub_binding_helper glue code
+               if ( writer.fDyldHelper == NULL )
+                       throw "symbol dyld_stub_binding_helper not defined (usually in crt1.o/dylib1.o/bundle1.o)";
+               lp = new LazyPointerAtom<arm>(writer, *writer.fDyldHelper, *this, forLazyDylib);
+       }
+       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)
 {
@@ -1331,9 +1478,22 @@ uint64_t StubAtom<ppc64>::getSize() const
        return ( pic() ? 32 : 16 );
 }
 
+
+template <>
+uint64_t StubAtom<arm>::getSize() const
+{
+       return ( pic() ? 16 : 12 );
+}
+
 template <>
 uint64_t StubAtom<x86>::getSize() const
 {
+       if ( fWriter.fOptions.slowx86Stubs() || fForLazyDylib ) {
+               if ( pic() )
+                       return 20;
+               else
+                       return 16;
+       }
        return 5;
 }
 
@@ -1346,8 +1506,10 @@ uint64_t StubAtom<x86_64>::getSize() const
 template <>
 ObjectFile::Alignment StubAtom<x86>::getAlignment() const
 {
-       // special case x86 fast stubs to be byte aligned
-       return 0;
+       if ( fWriter.fOptions.slowx86Stubs() || fForLazyDylib ) 
+               return 2;
+       else
+               return 0; // special case x86 fast stubs to be byte aligned
 }
 
 template <>
@@ -1395,21 +1557,65 @@ void StubAtom<ppc>::copyRawContent(uint8_t buffer[]) const
 template <>
 void StubAtom<x86>::copyRawContent(uint8_t buffer[]) const
 {
-       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;
+       if ( fWriter.fOptions.slowx86Stubs() || fForLazyDylib ) {
+               if ( pic() ) {
+                       buffer[0] = 0xE8;               // call picbase
+                       buffer[1] = 0x00;
+                       buffer[2] = 0x00;
+                       buffer[3] = 0x00;
+                       buffer[4] = 0x00;
+                       buffer[5] = 0x58;               // pop eax
+                       buffer[6] = 0x8D;               // lea foo$lazy_pointer-picbase(eax),eax
+                       buffer[7] = 0x80;
+                       buffer[8] = 0x00;
+                       buffer[9] = 0x00;
+                       buffer[10] = 0x00;
+                       buffer[11] = 0x00;
+                       buffer[12] = 0xFF;              // jmp *(eax)
+                       buffer[13] = 0x20;
+                       buffer[14] = 0x50;              // push eax
+                       buffer[15] = 0xE9;              // jump dyld_stub_binding_helper
+                       buffer[16] = 0x00;
+                       buffer[17] = 0x00;
+                       buffer[18] = 0x00;
+                       buffer[19] = 0x00;
+               }
+               else {  
+                       buffer[0] = 0xFF;               // jmp *foo$lazy_pointer
+                       buffer[1] = 0x25;
+                       buffer[2] = 0x00;
+                       buffer[3] = 0x00;
+                       buffer[4] = 0x00;
+                       buffer[5] = 0x00;               
+                       buffer[6] = 0x68;               // pushl $foo$lazy_pointer
+                       buffer[7] = 0x00;
+                       buffer[8] = 0x00;
+                       buffer[9] = 0x00;
+                       buffer[10] = 0x00;
+                       buffer[11] = 0xE9;              // jump dyld_stub_binding_helper
+                       buffer[12] = 0x00;
+                       buffer[13] = 0x00;
+                       buffer[14] = 0x00;
+                       buffer[15] = 0x00;
+               }
        }
        else {
-               buffer[0] = 0xF4;
-               buffer[1] = 0xF4;
-               buffer[2] = 0xF4;
-               buffer[3] = 0xF4;
-               buffer[4] = 0xF4;
+               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;
+               }
        }
 }
 
@@ -1424,6 +1630,22 @@ void StubAtom<x86_64>::copyRawContent(uint8_t buffer[]) const
        buffer[5] = 0x00;
 }
 
+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
+       }
+}
+
 // x86_64 stubs are 7 bytes and need no alignment
 template <>
 ObjectFile::Alignment StubAtom<x86_64>::getAlignment() const
@@ -1443,9 +1665,21 @@ const char*      StubAtom<ppc64>::getSectionName() const
        return ( pic() ? "__picsymbolstub1" : "__symbol_stub1");
 }
 
+template <>
+const char*    StubAtom<arm>::getSectionName() const
+{
+       return ( pic() ? "__picsymbolstub4" : "__symbol_stub4");
+}
+
 template <>
 const char*    StubAtom<x86>::getSectionName() const
 {
+       if ( fWriter.fOptions.slowx86Stubs() || fForLazyDylib ) {
+               if ( pic() ) 
+                       return "__picsymbol_stub";
+               else
+                       return "__symbol_stub";
+       }
        return "__jump_table";
 }
 
@@ -1476,29 +1710,21 @@ struct ExternalRelocSorter
 
 template <typename A>
 Writer<A>::Writer(const char* path, Options& options, std::vector<ExecutableFile::DyLibUsed>& dynamicLibraries)
-       : ExecutableFile::Writer(dynamicLibraries), fFilePath(strdup(path)), fOptions(options), fLoadCommandsSection(NULL),
-         fLoadCommandsSegment(NULL), fPadSegmentInfo(NULL),  fSplitCodeToDataContentAtom(NULL), fModuleInfoAtom(NULL), 
-         fPageZeroAtom(NULL),  fSymbolTableCount(0),  fLargestAtomSize(1), 
-        fEmitVirtualSections(false), fHasWeakExports(false), fReferencesWeakImports(false), 
-         fCanScatter(false), fWritableSegmentPastFirst4GB(false), fNoReExportedDylibs(false), fSlideable(false), 
+       : ExecutableFile::Writer(dynamicLibraries), fFilePath(strdup(path)), fOptions(options), 
+         fAllAtoms(NULL), fStabs(NULL), fLoadCommandsSection(NULL),
+         fLoadCommandsSegment(NULL), fEncryptionLoadCommand(NULL), fSegmentCommands(NULL), 
+         fSymbolTableCommands(NULL), fHeaderPadding(NULL),
+         fUUIDAtom(NULL), fPadSegmentInfo(NULL), fEntryPoint( NULL), fDyldHelper(NULL), fDyldLazyDylibHelper(NULL),
+         fSectionRelocationsAtom(NULL), fLocalRelocationsAtom(NULL), fExternalRelocationsAtom(NULL),
+         fSymbolTableAtom(NULL), fSplitCodeToDataContentAtom(NULL), fIndirectTableAtom(NULL), fModuleInfoAtom(NULL), 
+         fStringsAtom(NULL), fPageZeroAtom(NULL), fSymbolTable(NULL),  fSymbolTableCount(0), fSymbolTableStabsCount(0),
+         fSymbolTableLocalCount(0), fSymbolTableExportCount(0), fSymbolTableImportCount(0), 
+         fLargestAtomSize(1), 
+         fEmitVirtualSections(false), fHasWeakExports(false), fReferencesWeakImports(false), 
+         fCanScatter(false), fWritableSegmentPastFirst4GB(false), fNoReExportedDylibs(false), 
+         fBiggerThanTwoGigs(false), fSlideable(false), 
          fFirstWritableSegment(NULL), fAnonNameIndex(1000)
 {
-       // for UNIX conformance, error if file exists and is not writable
-       if ( (access(path, F_OK) == 0) && (access(path, W_OK) == -1) )
-               throwf("can't write output file: %s", path);
-
-       int permissions = 0777;
-       if ( fOptions.outputKind() == Options::kObjectFile )
-               permissions = 0666;
-       // Calling unlink first assures the file is gone so that open creates it with correct permissions
-       // It also handles the case where fFilePath file is not writable but its directory is
-       // And it means we don't have to truncate the file when done writing (in case new is smaller than old)
-       (void)unlink(fFilePath);
-       fFileDescriptor = open(fFilePath, O_CREAT | O_WRONLY | O_TRUNC, permissions);
-       if ( fFileDescriptor == -1 ) {
-               throwf("can't open output file for writing: %s", path);
-       }
-
        switch ( fOptions.outputKind() ) {
                case Options::kDynamicExecutable:
                case Options::kStaticExecutable:
@@ -1571,9 +1797,14 @@ Writer<A>::Writer(const char* path, Options& options, std::vector<ExecutableFile
 
        // add extra commmands
        bool hasReExports = false;
-       uint8_t ordinal = 1;
+       uint32_t ordinal = 1;
        switch ( fOptions.outputKind() ) {
                case Options::kDynamicExecutable:
+                       if ( fOptions.makeEncryptable() ) {
+                               fEncryptionLoadCommand = new EncryptionLoadCommandsAtom<A>(*this);
+                               fWriterSynthesizedAtoms.push_back(fEncryptionLoadCommand);
+                       }
+                       // fall through
                case Options::kDynamicLibrary:
                case Options::kDynamicBundle:
                        {
@@ -1772,16 +2003,19 @@ 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* dyldHelperAtom,
+                                                 class ObjectFile::Atom* dyldLazyDylibHelperAtom,
                                                  bool createUUID, bool canScatter, ObjectFile::Reader::CpuConstraint cpuConstraint,
-                                                 bool biggerThanTwoGigs)
+                                                 bool biggerThanTwoGigs, bool overridesDylibWeakDefines)
 {
        fAllAtoms =  &atoms;
        fStabs =  &stabs;
        fEntryPoint = entryPointAtom;
        fDyldHelper = dyldHelperAtom;
+       fDyldLazyDylibHelper = dyldLazyDylibHelperAtom;
        fCanScatter = canScatter;
        fCpuConstraint = cpuConstraint;
        fBiggerThanTwoGigs = biggerThanTwoGigs;
+       fHasWeakExports = overridesDylibWeakDefines; // dyld needs to search this image as if it had weak exports
 
        try {
                // Set for create UUID
@@ -1791,7 +2025,7 @@ uint64_t Writer<A>::write(std::vector<class ObjectFile::Atom*>& atoms,
                // remove uneeded dylib load commands
                optimizeDylibReferences();
 
-               // check for mdynamic-no-pic codegen which force code into low 4GB
+               // check for mdynamic-no-pic codegen
                scanForAbsoluteReferences();
 
                // create inter-library stubs
@@ -1820,7 +2054,6 @@ uint64_t Writer<A>::write(std::vector<class ObjectFile::Atom*>& atoms,
                return writeAtoms();
        } catch (...) {
                // clean up if any errors
-               close(fFileDescriptor);
                (void)unlink(fFilePath);
                throw;
        }
@@ -1892,12 +2125,14 @@ void Writer<A>::setExportNlist(const ObjectFile::Atom* atom, macho_nlist<P>* ent
 
        // set n_desc
        uint16_t desc = 0;
-       if ( atom->getSymbolTableInclusion() == ObjectFile::Atom::kSymbolTableInAndNeverStrip )
-               desc |= REFERENCED_DYNAMICALLY;
-       if ( atom->getDefinitionKind() == ObjectFile::Atom::kWeakDefinition ) {
-               desc |= N_WEAK_DEF;
-               fHasWeakExports = true;
-       }
+    if ( atom->isThumb() )
+        desc |= N_ARM_THUMB_DEF;
+    if ( atom->getSymbolTableInclusion() == ObjectFile::Atom::kSymbolTableInAndNeverStrip )
+        desc |= REFERENCED_DYNAMICALLY;
+    if ( atom->getDefinitionKind() == ObjectFile::Atom::kWeakDefinition ) {
+        desc |= N_WEAK_DEF;
+        fHasWeakExports = true;
+    }
        entry->set_n_desc(desc);
 
        // set n_value ( address this symbol will be at if this executable is loaded at it preferred address )
@@ -1930,7 +2165,7 @@ void Writer<A>::setImportNlist(const ObjectFile::Atom* atom, macho_nlist<P>* ent
        if ( fOptions.outputKind() != Options::kObjectFile ) {
                // set n_desc ( high byte is library ordinal, low byte is reference type )
                std::map<const ObjectFile::Atom*,ObjectFile::Atom*>::iterator pos = fStubsMap.find(atom);
-               if ( pos != fStubsMap.end() )
+               if ( pos != fStubsMap.end() || ( strncmp(atom->getName(), ".objc_class_name_", 17) == 0) )
                        desc = REFERENCE_FLAG_UNDEFINED_LAZY;
                else
                        desc = REFERENCE_FLAG_UNDEFINED_NON_LAZY;
@@ -1945,10 +2180,11 @@ void Writer<A>::setImportNlist(const ObjectFile::Atom* atom, macho_nlist<P>* ent
        }
        else if ( atom->getDefinitionKind() == ObjectFile::Atom::kTentativeDefinition ) {
                uint8_t align = atom->getAlignment().powerOf2;
-               // if alignment does not match size, then record the custom alignment
-               if ( align != __builtin_ctz(atom->getSize()) )
-                       SET_COMM_ALIGN(desc, align);
+               // always record custom alignment of common symbols to match what compiler does
+               SET_COMM_ALIGN(desc, align);
        }
+       if ( atom->isThumb() )
+               desc |= N_ARM_THUMB_DEF;
        if ( atom->getSymbolTableInclusion() == ObjectFile::Atom::kSymbolTableInAndNeverStrip )
                desc |= REFERENCED_DYNAMICALLY;
        if ( ( fOptions.outputKind() != Options::kObjectFile) && (atom->getDefinitionKind() == ObjectFile::Atom::kExternalWeakDefinition) ) {
@@ -1998,6 +2234,8 @@ void Writer<A>::setLocalNlist(const ObjectFile::Atom* atom, macho_nlist<P>* entr
        uint16_t desc = 0;
        if ( atom->getDefinitionKind() == ObjectFile::Atom::kWeakDefinition )
                desc |= N_WEAK_DEF;
+       if ( atom->isThumb() )
+               desc |= N_ARM_THUMB_DEF;
        entry->set_n_desc(desc);
 
        // set n_value ( address this symbol will be at if this executable is loaded at it preferred address )
@@ -2196,7 +2434,7 @@ void Writer<A>::collectExportedAndImportedAndLocalAtoms()
                        }
                }
                // when geneating a .o file, dtrace static probes become local labels
-               if ( fOptions.outputKind() == Options::kObjectFile) {
+               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;
@@ -2207,7 +2445,7 @@ void Writer<A>::collectExportedAndImportedAndLocalAtoms()
                        }
                }
                // when linking kernel, old style dtrace static probes become global labels
-               else if ( fOptions.outputKind() == Options::kStaticExecutable ) {
+               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;
@@ -2421,6 +2659,7 @@ uint32_t Writer<x86_64>::addObjectRelocs(ObjectFile::Atom* atom, ObjectFile::Ref
        switch ( kind ) {
                case x86_64::kNoFixUp:
                case x86_64::kFollowOn:
+               case x86_64::kGroupSubordinate:
                        return 0;
 
                case x86_64::kPointer:
@@ -2510,6 +2749,16 @@ uint32_t Writer<x86_64>::addObjectRelocs(ObjectFile::Atom* atom, ObjectFile::Ref
                        fSectionRelocs.push_back(reloc1);
                        return 1;
 
+               case x86_64::kBranchPCRel8:
+                       reloc1.set_r_address(address);
+                       reloc1.set_r_symbolnum(symbolIndex);
+                       reloc1.set_r_pcrel(true);
+                       reloc1.set_r_length(0);
+                       reloc1.set_r_extern(external);
+                       reloc1.set_r_type(X86_64_RELOC_BRANCH);
+                       fSectionRelocs.push_back(reloc1);
+                       return 1;
+
                case x86_64::kPCRel32GOT:
                case x86_64::kPCRel32GOTWeakImport:
                        reloc1.set_r_address(address);
@@ -2558,13 +2807,14 @@ uint32_t Writer<x86>::addObjectRelocs(ObjectFile::Atom* atom, ObjectFile::Refere
        x86::ReferenceKinds kind = (x86::ReferenceKinds)ref->getKind();
        
        if ( !isExtern && (sectionNum == 0) && (target.getDefinitionKind() != ObjectFile::Atom::kAbsoluteSymbol) )
-               fprintf(stderr, "ld: warning section index == 0 for %s (kind=%d, scope=%d, inclusion=%d) in %s\n",
+               warning("section index == 0 for %s (kind=%d, scope=%d, inclusion=%d) in %s",
                 target.getDisplayName(), target.getDefinitionKind(), target.getScope(), target.getSymbolTableInclusion(), target.getFile()->getPath());
 
 
        switch ( kind ) {
                case x86::kNoFixUp:
                case x86::kFollowOn:
+               case x86::kGroupSubordinate:
                        return 0;
 
                case x86::kPointer:
@@ -2611,10 +2861,7 @@ uint32_t Writer<x86>::addObjectRelocs(ObjectFile::Atom* atom, ObjectFile::Refere
                                sreloc2->set_r_length( (kind==x86::kPointerDiff) ? 2 : 1 );
                                sreloc2->set_r_type(GENERIC_RELOC_PAIR);
                                sreloc2->set_r_address(0);
-                               //if ( &ref->getFromTarget() == &ref->getTarget() )
-                                       sreloc2->set_r_value(ref->getFromTarget().getAddress() + ref->getFromTargetOffset());
-                               //else
-                               //      sreloc2->set_r_value(ref->getFromTarget().getAddress());
+                               sreloc2->set_r_value(ref->getFromTarget().getAddress()+ref->getFromTargetOffset());
                                fSectionRelocs.push_back(reloc2);
                                fSectionRelocs.push_back(reloc1);
                                return 2;
@@ -2623,13 +2870,14 @@ uint32_t Writer<x86>::addObjectRelocs(ObjectFile::Atom* atom, ObjectFile::Refere
                case x86::kPCRel32WeakImport:
                case x86::kPCRel32:
                case x86::kPCRel16:
+               case x86::kPCRel8:
                case x86::kDtraceProbeSite:
                case x86::kDtraceIsEnabledSite:
                        if ( !isExtern && (ref->getTargetOffset() != 0) ) {
                                // use scattered reloc is target offset is non-zero
                                sreloc1->set_r_scattered(true);
                                sreloc1->set_r_pcrel(true);
-                               sreloc1->set_r_length( (kind==x86::kPCRel16) ? 1 : 2);
+                               sreloc1->set_r_length( (kind==x86::kPCRel8) ? 0 : ((kind==x86::kPCRel16) ? 1 : 2) );
                                sreloc1->set_r_type(GENERIC_RELOC_VANILLA);
                                sreloc1->set_r_address(address);
                                sreloc1->set_r_value(target.getAddress());
@@ -2638,7 +2886,7 @@ uint32_t Writer<x86>::addObjectRelocs(ObjectFile::Atom* atom, ObjectFile::Refere
                                reloc1.set_r_address(address);
                                reloc1.set_r_symbolnum(isExtern ? symbolIndex : sectionNum);
                                reloc1.set_r_pcrel(true);
-                               reloc1.set_r_length( (kind==x86::kPCRel16) ? 1 : 2);
+                               reloc1.set_r_length( (kind==x86::kPCRel8) ? 0 : ((kind==x86::kPCRel16) ? 1 : 2) );
                                reloc1.set_r_extern(isExtern);
                                reloc1.set_r_type(GENERIC_RELOC_VANILLA);
                        }
@@ -2654,14 +2902,137 @@ uint32_t Writer<x86>::addObjectRelocs(ObjectFile::Atom* atom, ObjectFile::Refere
        return 0;
 }
 
+template <>
+uint32_t Writer<arm>::addObjectRelocs(ObjectFile::Atom* atom, ObjectFile::Reference* ref)
+{
+       ObjectFile::Atom& target = ref->getTarget();
+       bool isExtern = this->makesExternalRelocatableReference(target);
+       uint32_t symbolIndex = 0;
+       if ( isExtern )
+               symbolIndex = this->symbolIndex(target);
+       uint32_t sectionNum = target.getSection()->getIndex();
+       uint32_t address = atom->getSectionOffset()+ref->getFixUpOffset();
+       macho_relocation_info<P> reloc1;
+       macho_relocation_info<P> reloc2;
+       macho_scattered_relocation_info<P>* sreloc1 = (macho_scattered_relocation_info<P>*)&reloc1;
+       macho_scattered_relocation_info<P>* sreloc2 = (macho_scattered_relocation_info<P>*)&reloc2;
+       arm::ReferenceKinds kind = (arm::ReferenceKinds)ref->getKind();
+       
+       if ( !isExtern && (sectionNum == 0) && (target.getDefinitionKind() != ObjectFile::Atom::kAbsoluteSymbol) )
+               warning("section index == 0 for %s (kind=%d, scope=%d, inclusion=%d) in %s",
+                target.getDisplayName(), target.getDefinitionKind(), target.getScope(), target.getSymbolTableInclusion(), target.getFile()->getPath());
+
 
+       switch ( kind ) {
+               case arm::kNoFixUp:
+               case arm::kFollowOn:
+               case arm::kGroupSubordinate:
+                       return 0;
 
+               case arm::kPointer:
+               case arm::kPointerWeakImport:
+                       if ( !isExtern && (ref->getTargetOffset() != 0) ) {
+                               // use scattered reloc is target offset is non-zero
+                               sreloc1->set_r_scattered(true);
+                               sreloc1->set_r_pcrel(false);
+                               sreloc1->set_r_length(2);
+                               sreloc1->set_r_type(ARM_RELOC_VANILLA);
+                               sreloc1->set_r_address(address);
+                               sreloc1->set_r_value(target.getAddress());
+                       }
+                       else {
+                               reloc1.set_r_address(address);
+                               reloc1.set_r_symbolnum(isExtern ? symbolIndex : sectionNum);
+                               reloc1.set_r_pcrel(false);
+                               reloc1.set_r_length(2);
+                               reloc1.set_r_extern(isExtern);
+                               reloc1.set_r_type(ARM_RELOC_VANILLA);
+                       }
+                       fSectionRelocs.push_back(reloc1);
+                       return 1;
+
+               case arm::kPointerDiff:
+                       {
+                               sreloc1->set_r_scattered(true);
+                               sreloc1->set_r_pcrel(false);
+                               sreloc1->set_r_length(2);
+                               if ( ref->getTarget().getScope() == ObjectFile::Atom::scopeTranslationUnit )
+                                       sreloc1->set_r_type(ARM_RELOC_LOCAL_SECTDIFF);
+                               else
+                                       sreloc1->set_r_type(ARM_RELOC_SECTDIFF);
+                               sreloc1->set_r_address(address);
+                               sreloc1->set_r_value(target.getAddress());
+                               sreloc2->set_r_scattered(true);
+                               sreloc2->set_r_pcrel(false);
+                               sreloc2->set_r_length(2);
+                               sreloc2->set_r_type(ARM_RELOC_PAIR);
+                               sreloc2->set_r_address(0);
+                               sreloc2->set_r_value(ref->getFromTarget().getAddress()+ref->getFromTargetOffset());
+                               fSectionRelocs.push_back(reloc2);
+                               fSectionRelocs.push_back(reloc1);
+                               return 2;
+                       }
+
+               case arm::kBranch24WeakImport:
+               case arm::kBranch24:
+               case arm::kDtraceProbeSite:
+               case arm::kDtraceIsEnabledSite:
+                       if ( !isExtern && (ref->getTargetOffset() != 0) ) {
+                               // use scattered reloc is target offset is non-zero
+                               sreloc1->set_r_scattered(true);
+                               sreloc1->set_r_pcrel(true);
+                               sreloc1->set_r_length(2);
+                               sreloc1->set_r_type(ARM_RELOC_BR24);
+                               sreloc1->set_r_address(address);
+                               sreloc1->set_r_value(target.getAddress());
+                       }
+                       else {
+                               reloc1.set_r_address(address);
+                               reloc1.set_r_symbolnum(isExtern ? symbolIndex : sectionNum);
+                               reloc1.set_r_pcrel(true);
+                               reloc1.set_r_length(2);
+                               reloc1.set_r_extern(isExtern);
+                               reloc1.set_r_type(ARM_RELOC_BR24);
+                       }
+                       fSectionRelocs.push_back(reloc1);
+                       return 1;
+                       
+               case arm::kThumbBranch22WeakImport:
+               case arm::kThumbBranch22:
+                       if ( !isExtern && (ref->getTargetOffset() != 0) ) {
+                               // use scattered reloc is target offset is non-zero
+                               sreloc1->set_r_scattered(true);
+                               sreloc1->set_r_pcrel(true);
+                               sreloc1->set_r_length(2);
+                               sreloc1->set_r_type(ARM_THUMB_RELOC_BR22);
+                               sreloc1->set_r_address(address);
+                               sreloc1->set_r_value(target.getAddress());
+                       }
+                       else {
+                               reloc1.set_r_address(address);
+                               reloc1.set_r_symbolnum(isExtern ? symbolIndex : sectionNum);
+                               reloc1.set_r_pcrel(true);
+                               reloc1.set_r_length(2);
+                               reloc1.set_r_extern(isExtern);
+                               reloc1.set_r_type(ARM_THUMB_RELOC_BR22);
+                       }
+                       fSectionRelocs.push_back(reloc1);
+                       return 1;
+
+               case arm::kDtraceTypeReference:
+               case arm::kDtraceProbe:
+                       // generates no relocs
+                       return 0;
+
+       }
+       return 0;
+}
 
 template <> uint64_t    Writer<ppc>::maxAddress() { return 0xFFFFFFFFULL; }
 template <> uint64_t  Writer<ppc64>::maxAddress() { return 0xFFFFFFFFFFFFFFFFULL; }
 template <> uint64_t    Writer<x86>::maxAddress() { return 0xFFFFFFFFULL; }
 template <> uint64_t Writer<x86_64>::maxAddress() { return 0xFFFFFFFFFFFFFFFFULL; }
-
+template <> uint64_t    Writer<arm>::maxAddress() { return 0xFFFFFFFFULL; }
 
 template <>
 uint8_t Writer<ppc>::getRelocPointerSize()
@@ -2710,6 +3081,7 @@ uint32_t Writer<A>::addObjectRelocs_powerpc(ObjectFile::Atom* atom, ObjectFile::
        switch ( kind ) {
                case A::kNoFixUp:
                case A::kFollowOn:
+               case A::kGroupSubordinate:
                        return 0;
 
                case A::kPointer:
@@ -2741,20 +3113,21 @@ uint32_t Writer<A>::addObjectRelocs_powerpc(ObjectFile::Atom* atom, ObjectFile::
                case A::kPointerDiff32:
                case A::kPointerDiff64:
                        {
-                               pint_t toAddr = target.getAddress() + ref->getTargetOffset();
-                               pint_t fromAddr = ref->getFromTarget().getAddress() + ref->getFromTargetOffset();
                                sreloc1->set_r_scattered(true);
                                sreloc1->set_r_pcrel(false);
                                sreloc1->set_r_length( (kind == A::kPointerDiff32) ? 2 : ((kind == A::kPointerDiff64) ? 3 : 1));
-                               sreloc1->set_r_type(ref->getTargetOffset() != 0 ? PPC_RELOC_LOCAL_SECTDIFF : PPC_RELOC_SECTDIFF);
+                               if ( ref->getTarget().getScope() == ObjectFile::Atom::scopeTranslationUnit )
+                                       sreloc1->set_r_type(PPC_RELOC_LOCAL_SECTDIFF);
+                               else
+                                       sreloc1->set_r_type(PPC_RELOC_SECTDIFF);
                                sreloc1->set_r_address(address);
-                               sreloc1->set_r_value(toAddr);
+                               sreloc1->set_r_value(target.getAddress()); 
                                sreloc2->set_r_scattered(true);
                                sreloc2->set_r_pcrel(false);
-                               sreloc1->set_r_length( (kind == A::kPointerDiff32) ? 2 : ((kind == A::kPointerDiff64) ? 3 : 1));
+                               sreloc2->set_r_length(sreloc1->r_length());
                                sreloc2->set_r_type(PPC_RELOC_PAIR);
                                sreloc2->set_r_address(0);
-                               sreloc2->set_r_value(fromAddr);
+                               sreloc2->set_r_value(ref->getFromTarget().getAddress()+ref->getFromTargetOffset()); 
                                fSectionRelocs.push_back(reloc2);
                                fSectionRelocs.push_back(reloc1);
                                return 2;
@@ -3003,7 +3376,8 @@ void Writer<A>::buildObjectFileFixups()
                        //fprintf(stderr, "buildObjectFileFixups(): starting section %s\n", curSection->fSectionName);
                        std::vector<ObjectFile::Atom*>& sectionAtoms = curSection->fAtoms;
                        if ( ! curSection->fAllZeroFill ) {
-                               if ( curSection->fAllNonLazyPointers || curSection->fAllLazyPointers || curSection->fAllStubs )
+                               if ( curSection->fAllNonLazyPointers || curSection->fAllLazyPointers
+                                                       || curSection->fAllLazyDylibPointers || curSection->fAllStubs )
                                        curSection->fIndirectSymbolOffset = fIndirectTableAtom->fTable.size();
                                curSection->fRelocOffset = relocIndex;
                                const int atomCount = sectionAtoms.size();
@@ -3014,7 +3388,8 @@ void Writer<A>::buildObjectFileFixups()
                                        const int refCount = refs.size();
                                        for (int l=0; l < refCount; ++l) {
                                                ObjectFile::Reference* ref = refs[l];
-                                               if ( curSection->fAllNonLazyPointers || curSection->fAllLazyPointers || curSection->fAllStubs ) {
+                                               if ( curSection->fAllNonLazyPointers || curSection->fAllLazyPointers 
+                                                                               || curSection->fAllLazyDylibPointers || curSection->fAllStubs ) {
                                                        uint32_t offsetInSection = atom->getSectionOffset();
                                                        uint32_t indexInSection = offsetInSection / atom->getSize();
                                                        uint32_t undefinedSymbolIndex;
@@ -3043,7 +3418,7 @@ void Writer<A>::buildObjectFileFixups()
                                                                ObjectFile::Atom& target = ref->getTarget();
                                                                ObjectFile::Atom& fromTarget = ref->getFromTarget();
                                                                if ( &fromTarget == NULL ) {
-                                                                       fprintf(stderr, "lazy pointer %s missing initial binding\n", atom->getDisplayName());
+                                                                       warning("lazy pointer %s missing initial binding", atom->getDisplayName());
                                                                }
                                                                else {
                                                                        bool isExtern = ( ((target.getDefinitionKind() == ObjectFile::Atom::kExternalDefinition)
@@ -3147,6 +3522,156 @@ bool Writer<x86_64>::illegalRelocInFinalLinkedImage(const ObjectFile::Reference&
        return false;
 }
 
+template <>
+bool Writer<arm>::illegalRelocInFinalLinkedImage(const ObjectFile::Reference& ref)
+{
+       return false;
+}
+
+template <>
+bool Writer<x86>::generatesLocalTextReloc(const ObjectFile::Reference& ref, const ObjectFile::Atom& atom, SectionInfo* atomSection)
+{
+       if ( ref.getKind() == x86::kAbsolute32 ) {
+               switch ( ref.getTarget().getDefinitionKind() ) {
+                       case ObjectFile::Atom::kTentativeDefinition:
+                       case ObjectFile::Atom::kRegularDefinition:
+                       case ObjectFile::Atom::kWeakDefinition:
+                               // a reference to the absolute address of something in this same linkage unit can be 
+                               // encoded as a local text reloc in a dylib or bundle 
+                               if ( fSlideable ) {
+                                       macho_relocation_info<P> reloc;
+                                       SectionInfo* sectInfo = (SectionInfo*)(ref.getTarget().getSection());
+                                       reloc.set_r_address(this->relocAddressInFinalLinkedImage(atom.getAddress() + ref.getFixUpOffset(), &atom));
+                                       reloc.set_r_symbolnum(sectInfo->getIndex());
+                                       reloc.set_r_pcrel(false);
+                                       reloc.set_r_length();
+                                       reloc.set_r_extern(false);
+                                       reloc.set_r_type(GENERIC_RELOC_VANILLA);
+                                       fInternalRelocs.push_back(reloc);
+                                       atomSection->fHasTextLocalRelocs = true;
+                                       return true;
+                               }
+                               return false;
+                       case ObjectFile::Atom::kExternalDefinition:
+                       case ObjectFile::Atom::kExternalWeakDefinition:
+                       case ObjectFile::Atom::kAbsoluteSymbol:
+                               return false;
+               }
+       }
+       return false;
+}
+
+template <>
+bool Writer<ppc>::generatesLocalTextReloc(const ObjectFile::Reference& ref, const ObjectFile::Atom& atom, SectionInfo* atomSection)
+{
+       macho_relocation_info<P> reloc1;
+       macho_relocation_info<P> reloc2;
+       switch ( ref.getTarget().getDefinitionKind() ) {
+               case ObjectFile::Atom::kTentativeDefinition:
+               case ObjectFile::Atom::kRegularDefinition:
+               case ObjectFile::Atom::kWeakDefinition:
+                       switch ( ref.getKind() ) {
+                               case ppc::kAbsLow16:
+                               case ppc::kAbsLow14:
+                                       // a reference to the absolute address of something in this same linkage unit can be 
+                                       // encoded as a local text reloc in a dylib or bundle 
+                                       if ( fSlideable ) {
+                                               SectionInfo* sectInfo = (SectionInfo*)(ref.getTarget().getSection());
+                                               uint32_t targetAddr = ref.getTarget().getAddress() + ref.getTargetOffset();
+                                               reloc1.set_r_address(this->relocAddressInFinalLinkedImage(atom.getAddress() + ref.getFixUpOffset(), &atom));
+                                               reloc1.set_r_symbolnum(sectInfo->getIndex());
+                                               reloc1.set_r_pcrel(false);
+                                               reloc1.set_r_length(2);
+                                               reloc1.set_r_extern(false);
+                                               reloc1.set_r_type(ref.getKind()==ppc::kAbsLow16 ? PPC_RELOC_LO16 : PPC_RELOC_LO14);
+                                               reloc2.set_r_address(targetAddr >> 16);
+                                               reloc2.set_r_symbolnum(0);
+                                               reloc2.set_r_pcrel(false);
+                                               reloc2.set_r_length(2);
+                                               reloc2.set_r_extern(false);
+                                               reloc2.set_r_type(PPC_RELOC_PAIR);
+                                               fInternalRelocs.push_back(reloc1);
+                                               fInternalRelocs.push_back(reloc2);
+                                               atomSection->fHasTextLocalRelocs = true;
+                                               return true;
+                                       }
+                                       break;
+                               case ppc::kAbsHigh16:
+                               case ppc::kAbsHigh16AddLow:
+                                       if ( fSlideable ) {
+                                               SectionInfo* sectInfo = (SectionInfo*)(ref.getTarget().getSection());
+                                               uint32_t targetAddr = ref.getTarget().getAddress() + ref.getTargetOffset();
+                                               reloc1.set_r_address(this->relocAddressInFinalLinkedImage(atom.getAddress() + ref.getFixUpOffset(), &atom));
+                                               reloc1.set_r_symbolnum(sectInfo->getIndex());
+                                               reloc1.set_r_pcrel(false);
+                                               reloc1.set_r_length(2);
+                                               reloc1.set_r_extern(false);
+                                               reloc1.set_r_type(ref.getKind()==ppc::kAbsHigh16AddLow ? PPC_RELOC_HA16 : PPC_RELOC_HI16);
+                                               reloc2.set_r_address(targetAddr & 0xFFFF);
+                                               reloc2.set_r_symbolnum(0);
+                                               reloc2.set_r_pcrel(false);
+                                               reloc2.set_r_length(2);
+                                               reloc2.set_r_extern(false);
+                                               reloc2.set_r_type(PPC_RELOC_PAIR);
+                                               fInternalRelocs.push_back(reloc1);
+                                               fInternalRelocs.push_back(reloc2);
+                                               atomSection->fHasTextLocalRelocs = true;
+                                               return true;
+                                       }
+                       }
+                       break;
+               case ObjectFile::Atom::kExternalDefinition:
+               case ObjectFile::Atom::kExternalWeakDefinition:
+               case ObjectFile::Atom::kAbsoluteSymbol:
+                       return false;
+       }
+       return false;
+}
+
+template <typename A>
+bool Writer<A>::generatesLocalTextReloc(const ObjectFile::Reference&, const ObjectFile::Atom& atom, SectionInfo* curSection)
+{
+       return false;
+}
+
+template <>
+bool Writer<x86>::generatesExternalTextReloc(const ObjectFile::Reference& ref, const ObjectFile::Atom& atom, SectionInfo* atomSection)
+{
+       if ( ref.getKind() == x86::kAbsolute32 ) {
+               macho_relocation_info<P> reloc;
+               switch ( ref.getTarget().getDefinitionKind() ) {
+                       case ObjectFile::Atom::kTentativeDefinition:
+                       case ObjectFile::Atom::kRegularDefinition:
+                       case ObjectFile::Atom::kWeakDefinition:
+                               return false;
+                       case ObjectFile::Atom::kExternalDefinition:
+                       case ObjectFile::Atom::kExternalWeakDefinition:
+                               // a reference to the absolute address of something in another linkage unit can be 
+                               // encoded as an external text reloc in a dylib or bundle 
+                               reloc.set_r_address(this->relocAddressInFinalLinkedImage(atom.getAddress() + ref.getFixUpOffset(), &atom));
+                               reloc.set_r_symbolnum(this->symbolIndex(ref.getTarget()));
+                               reloc.set_r_pcrel(false);
+                               reloc.set_r_length();
+                               reloc.set_r_extern(true);
+                               reloc.set_r_type(GENERIC_RELOC_VANILLA);
+                               fExternalRelocs.push_back(reloc);
+                               atomSection->fHasTextExternalRelocs = true;
+                               return true;
+                       case ObjectFile::Atom::kAbsoluteSymbol:
+                               return false;
+               }
+       }
+       return false;
+}
+
+template <typename A>
+bool Writer<A>::generatesExternalTextReloc(const ObjectFile::Reference&, const ObjectFile::Atom& atom, SectionInfo* curSection)
+{
+       return false;
+}
+
+
+
 
 template <typename A>
 typename Writer<A>::RelocKind Writer<A>::relocationNeededInFinalLinkedImage(const ObjectFile::Atom& target) const
@@ -3156,7 +3681,7 @@ typename Writer<A>::RelocKind Writer<A>::relocationNeededInFinalLinkedImage(cons
                case ObjectFile::Atom::kRegularDefinition:
                        // in main executables, the only way regular symbols are indirected is if -interposable is used
                        if ( fOptions.outputKind() == Options::kDynamicExecutable ) {
-                               if ( this->shouldExport(target) && fOptions.interposable() )
+                               if ( this->shouldExport(target) && fOptions.interposable(target.getName()) )
                                        return kRelocExternal;
                                else if ( fSlideable )
                                        return kRelocInternal;
@@ -3168,7 +3693,7 @@ typename Writer<A>::RelocKind Writer<A>::relocationNeededInFinalLinkedImage(cons
                        else if ( this->shouldExport(target) &&
                           ((fOptions.nameSpace() == Options::kFlatNameSpace)
                          || (fOptions.nameSpace() == Options::kForceFlatNameSpace)
-                         || fOptions.interposable()) 
+                         || fOptions.interposable(target.getName())) 
                          && (target.getName() != NULL) 
                          && (strncmp(target.getName(), ".objc_class_", 12) != 0) ) // <rdar://problem/5254468>
                                return kRelocExternal;
@@ -3258,7 +3783,7 @@ template <> bool    Writer<ppc>::preboundLazyPointerType(uint8_t* type) { *type
 template <> bool  Writer<ppc64>::preboundLazyPointerType(uint8_t* type) { throw "prebinding not supported"; }
 template <> bool    Writer<x86>::preboundLazyPointerType(uint8_t* type) { *type = GENERIC_RELOC_PB_LA_PTR; return true; }
 template <> bool Writer<x86_64>::preboundLazyPointerType(uint8_t* type) { throw "prebinding not supported"; }
-
+template <> bool    Writer<arm>::preboundLazyPointerType(uint8_t* type) { *type = ARM_RELOC_PB_LA_PTR; return true; }
 
 template <typename A>
 void Writer<A>::buildExecutableFixups()
@@ -3275,7 +3800,8 @@ void Writer<A>::buildExecutableFixups()
                        //fprintf(stderr, "starting section %s\n", curSection->fSectionName);
                        std::vector<ObjectFile::Atom*>& sectionAtoms = curSection->fAtoms;
                        if ( ! curSection->fAllZeroFill ) {
-                               if ( curSection->fAllNonLazyPointers || curSection->fAllLazyPointers || curSection->fAllStubs || curSection->fAllSelfModifyingStubs )
+                               if ( curSection->fAllNonLazyPointers || curSection->fAllLazyPointers || curSection->fAllLazyDylibPointers 
+                                                                                               || curSection->fAllStubs || curSection->fAllSelfModifyingStubs )
                                        curSection->fIndirectSymbolOffset = fIndirectTableAtom->fTable.size();
                                const int atomCount = sectionAtoms.size();
                                for (int k=0; k < atomCount; ++k) {
@@ -3285,13 +3811,13 @@ void Writer<A>::buildExecutableFixups()
                                        //fprintf(stderr, "atom %s has %d references in section %s, %p\n", atom->getDisplayName(), refCount, curSection->fSectionName, atom->getSection());
                                        for (int l=0; l < refCount; ++l) {
                                                ObjectFile::Reference* ref = refs[l];
-                                               if ( curSection->fAllNonLazyPointers || curSection->fAllLazyPointers ) {
+                                               if ( curSection->fAllNonLazyPointers || curSection->fAllLazyPointers || curSection->fAllLazyDylibPointers ) {
                                                        // if atom is in (non)lazy_pointer section, this is encoded as an indirect symbol
                                                        if ( atom->getSize() != sizeof(pint_t) ) {
-                                                               printf("wrong size pointer atom %s from file %s\n", atom->getDisplayName(), atom->getFile()->getPath());
+                                                               warning("wrong size pointer atom %s from file %s", atom->getDisplayName(), atom->getFile()->getPath());
                                                        }
                                                        ObjectFile::Atom* pointerTarget = &(ref->getTarget());
-                                                       if ( curSection->fAllLazyPointers ) {
+                                                       if ( curSection->fAllLazyPointers || curSection->fAllLazyDylibPointers ) {
                                                                pointerTarget = ((LazyPointerAtom<A>*)atom)->getTarget();
                                                        }
                                                        uint32_t offsetInSection = atom->getSectionOffset();
@@ -3301,11 +3827,13 @@ void Writer<A>::buildExecutableFixups()
                                                                undefinedSymbolIndex = this->symbolIndex(*pointerTarget);
                                                        uint32_t indirectTableIndex = indexInSection + curSection->fIndirectSymbolOffset;
                                                        IndirectEntry entry = { indirectTableIndex, undefinedSymbolIndex };
-                                                       //fprintf(stderr,"fIndirectTableAtom->fTable.add(%d-%d => 0x%X-%s), size=%lld\n", indexInSection, indirectTableIndex, undefinedSymbolIndex, ref->getTarget().getName(), atom->getSize());
+                                                       //fprintf(stderr,"fIndirectTableAtom->fTable.push_back(tableIndex=%d, symIndex=0x%X), pointerTarget=%s\n", 
+                                                       //              indirectTableIndex, undefinedSymbolIndex, pointerTarget->getDisplayName());
                                                        fIndirectTableAtom->fTable.push_back(entry);
-                                                       if ( curSection->fAllLazyPointers ) {
+                                                       if ( curSection->fAllLazyPointers || curSection->fAllLazyDylibPointers ) {
                                                                uint8_t preboundLazyType;
-                                                               if ( fOptions.prebind() && (fDyldHelper != NULL) && preboundLazyPointerType(&preboundLazyType) ) {
+                                                               if ( fOptions.prebind() && (fDyldHelper != NULL) 
+                                                                               && curSection->fAllLazyPointers && preboundLazyPointerType(&preboundLazyType) ) {
                                                                        // this is a prebound image, need special relocs for dyld to reset lazy pointers if prebinding is invalid
                                                                        macho_scattered_relocation_info<P> pblaReloc;
                                                                        pblaReloc.set_r_scattered(true);
@@ -3374,7 +3902,23 @@ void Writer<A>::buildExecutableFixups()
                                                        }
                                                }
                                                else if ( this->illegalRelocInFinalLinkedImage(*ref) ) {
-                                                       throwf("absolute addressing (perhaps -mdynamic-no-pic) used in %s from %s not allowed in slidable image", atom->getDisplayName(), atom->getFile()->getPath());
+                                                       if ( fOptions.allowTextRelocs() && !atom->getSegment().isContentWritable() ) {
+                                                               if ( fOptions.warnAboutTextRelocs() )
+                                                                       warning("text reloc in %s to %s", atom->getDisplayName(), ref->getTargetName());
+                                                               if (  this->generatesLocalTextReloc(*ref, *atom, curSection) ) {
+                                                                       // relocs added to fInternalRelocs
+                                                               }
+                                                               else if ( this->generatesExternalTextReloc(*ref, *atom, curSection) ) {
+                                                                       // relocs added to fExternalRelocs
+                                                               }
+                                                               else {
+                                                                       throwf("relocation used in %s from %s not allowed in slidable image", atom->getDisplayName(), atom->getFile()->getPath());
+                                                               }
+                                                       }
+                                                       else {
+                                                               throwf("absolute addressing (perhaps -mdynamic-no-pic) used in %s from %s not allowed in slidable image. "
+                                                                               "Use '-read_only_relocs suppress' to enable text relocs", atom->getDisplayName(), atom->getFile()->getPath());
+                                                       }
                                                }
                                        }
                                        if ( curSection->fAllSelfModifyingStubs || curSection->fAllStubs ) {
@@ -3410,6 +3954,7 @@ void Writer<ppc>::addCrossSegmentRef(const ObjectFile::Atom* atom, const ObjectF
                        fSplitCodeToDataContentAtom->add64bitPointerLocation(atom, ref->getFixUpOffset());
                        break;
                case ppc::kNoFixUp:
+               case ppc::kGroupSubordinate:
                case ppc::kPointer:
                case ppc::kPointerWeakImport:
                case ppc::kPICBaseLow16:
@@ -3417,7 +3962,7 @@ void Writer<ppc>::addCrossSegmentRef(const ObjectFile::Atom* atom, const ObjectF
                        // ignore
                        break;
                default:
-                       fprintf(stderr, "ld: warning codegen with reference kind %d in %s prevents image from loading in dyld shared cache\n", ref->getKind(), atom->getDisplayName());
+                       warning("codegen with reference kind %d in %s prevents image from loading in dyld shared cache", ref->getKind(), atom->getDisplayName());
                        fSplitCodeToDataContentAtom->setCantEncode();
        }
 }
@@ -3436,6 +3981,7 @@ void Writer<ppc64>::addCrossSegmentRef(const ObjectFile::Atom* atom, const Objec
                        fSplitCodeToDataContentAtom->add64bitPointerLocation(atom, ref->getFixUpOffset());
                        break;
                case ppc64::kNoFixUp:
+               case ppc64::kGroupSubordinate:
                case ppc64::kPointer:
                case ppc64::kPointerWeakImport:
                case ppc64::kPICBaseLow16:
@@ -3443,7 +3989,7 @@ void Writer<ppc64>::addCrossSegmentRef(const ObjectFile::Atom* atom, const Objec
                        // ignore
                        break;
                default:
-                       fprintf(stderr, "ld: warning codegen with reference kind %d in %s prevents image from loading in dyld shared cache\n", ref->getKind(), atom->getDisplayName());
+                       warning("codegen with reference kind %d in %s prevents image from loading in dyld shared cache", ref->getKind(), atom->getDisplayName());
                        fSplitCodeToDataContentAtom->setCantEncode();
        }
 }
@@ -3459,6 +4005,7 @@ void Writer<x86>::addCrossSegmentRef(const ObjectFile::Atom* atom, const ObjectF
                                fSplitCodeToDataContentAtom->add32bitPointerLocation(atom, ref->getFixUpOffset());
                        break;
                case x86::kNoFixUp:
+               case x86::kGroupSubordinate:
                case x86::kPointer:
                case x86::kPointerWeakImport:
                        // ignore
@@ -3472,7 +4019,7 @@ void Writer<x86>::addCrossSegmentRef(const ObjectFile::Atom* atom, const ObjectF
                        }
                        // fall into warning case
                default:
-                       fprintf(stderr, "ld: warning codegen in %s (offset 0x%08llX) prevents image from loading in dyld shared cache\n", atom->getDisplayName(), ref->getFixUpOffset());
+                       warning("codegen in %s (offset 0x%08llX) prevents image from loading in dyld shared cache", atom->getDisplayName(), ref->getFixUpOffset());
                        fSplitCodeToDataContentAtom->setCantEncode();
        }
 }
@@ -3496,15 +4043,34 @@ void Writer<x86_64>::addCrossSegmentRef(const ObjectFile::Atom* atom, const Obje
                        fSplitCodeToDataContentAtom->add64bitPointerLocation(atom, ref->getFixUpOffset());
                        break;
                case x86_64::kNoFixUp:
+               case x86_64::kGroupSubordinate:
                case x86_64::kPointer:
                        // ignore
                        break;
                default:
-                       fprintf(stderr, "ld: warning codegen in %s with kind %d prevents image from loading in dyld shared cache\n", atom->getDisplayName(), ref->getKind());
+                       warning("codegen in %s with kind %d prevents image from loading in dyld shared cache", atom->getDisplayName(), ref->getKind());
                        fSplitCodeToDataContentAtom->setCantEncode();
        }
 }
 
+template <>
+void Writer<arm>::addCrossSegmentRef(const ObjectFile::Atom* atom, const ObjectFile::Reference* ref)
+{
+       switch ( (arm::ReferenceKinds)ref->getKind()  ) {
+               case arm::kPointerDiff:
+                       fSplitCodeToDataContentAtom->add32bitPointerLocation(atom, ref->getFixUpOffset());
+                       break;
+               case arm::kNoFixUp:
+               case arm::kGroupSubordinate:
+               case arm::kPointer:
+    case arm::kPointerWeakImport:
+                       // ignore
+                       break;
+               default:
+                       warning("codegen in %s prevents image from loading in dyld shared cache", atom->getDisplayName());
+                       fSplitCodeToDataContentAtom->setCantEncode();
+       }
+}
 
 template <typename A>
 bool Writer<A>::segmentsCanSplitApart(const ObjectFile::Atom& from, const ObjectFile::Atom& to)
@@ -3526,39 +4092,48 @@ bool Writer<A>::segmentsCanSplitApart(const ObjectFile::Atom& from, const Object
 
 
 template <>
-void Writer<ppc>::writeNoOps(uint32_t from, uint32_t to)
+void Writer<ppc>::writeNoOps(int fd, uint32_t from, uint32_t to)
 {
        uint32_t ppcNop;
        OSWriteBigInt32(&ppcNop, 0, 0x60000000);
        for (uint32_t p=from; p < to; p += 4)
-               ::pwrite(fFileDescriptor, &ppcNop, 4, p);
+               ::pwrite(fd, &ppcNop, 4, p);
 }
 
 template <>
-void Writer<ppc64>::writeNoOps(uint32_t from, uint32_t to)
+void Writer<ppc64>::writeNoOps(int fd, uint32_t from, uint32_t to)
 {
        uint32_t ppcNop;
        OSWriteBigInt32(&ppcNop, 0, 0x60000000);
        for (uint32_t p=from; p < to; p += 4)
-               ::pwrite(fFileDescriptor, &ppcNop, 4, p);
+               ::pwrite(fd, &ppcNop, 4, p);
 }
 
 template <>
-void Writer<x86>::writeNoOps(uint32_t from, uint32_t to)
+void Writer<x86>::writeNoOps(int fd, uint32_t from, uint32_t to)
 {
        uint8_t x86Nop = 0x90;
        for (uint32_t p=from; p < to; ++p)
-               ::pwrite(fFileDescriptor, &x86Nop, 1, p);
+               ::pwrite(fd, &x86Nop, 1, p);
 }
 
 template <>
-void Writer<x86_64>::writeNoOps(uint32_t from, uint32_t to)
+void Writer<x86_64>::writeNoOps(int fd, uint32_t from, uint32_t to)
 {
        uint8_t x86Nop = 0x90;
        for (uint32_t p=from; p < to; ++p)
-               ::pwrite(fFileDescriptor, &x86Nop, 1, p);
+               ::pwrite(fd, &x86Nop, 1, p);
 }
 
+template <>
+void Writer<arm>::writeNoOps(int fd, uint32_t from, uint32_t to)
+{
+       // FIXME: need thumb nop?
+       uint32_t armNop;
+       OSWriteLittleInt32(&armNop, 0, 0xe1a00000);
+       for (uint32_t p=from; p < to; p += 4)
+               ::pwrite(fd, &armNop, 4, p);
+}
 
 template <>
 void Writer<ppc>::copyNoOps(uint8_t* from, uint8_t* to)
@@ -3588,6 +4163,13 @@ void Writer<x86_64>::copyNoOps(uint8_t* from, uint8_t* to)
                *p = 0x90;
 }
 
+template <>
+void Writer<arm>::copyNoOps(uint8_t* from, uint8_t* to)
+{
+    // fixme: need thumb nop?
+       for (uint8_t* p=from; p < to; p += 4)
+               OSWriteBigInt32((uint32_t*)p, 0, 0xe1a00000);
+}
 
 static const char* stringName(const char* str)
 {
@@ -3632,6 +4214,7 @@ template <> const char* Writer<ppc>::getArchString()    { return "ppc"; }
 template <> const char* Writer<ppc64>::getArchString()  { return "ppc64"; }
 template <> const char* Writer<x86>::getArchString()    { return "i386"; }
 template <> const char* Writer<x86_64>::getArchString() { return "x86_64"; }
+template <> const char* Writer<arm>::getArchString()    { return "arm"; }
 
 template <typename A>
 void Writer<A>::writeMap()
@@ -3714,166 +4297,605 @@ void Writer<A>::writeMap()
                        fclose(mapFile);
                }
                else {
-                       fprintf(stderr, "ld: warning could not write map file: %s\n", fOptions.generatedMapPath());
+                       warning("could not write map file: %s\n", fOptions.generatedMapPath());
                }
        }
 }
 
+static const char* sCleanupFile = NULL;
+static void cleanup(int sig)
+{
+       ::signal(sig, SIG_DFL);
+       if ( sCleanupFile != NULL ) {
+               ::unlink(sCleanupFile);
+       }
+       if ( sig == SIGINT )
+               ::exit(1);
+}
+
+
 template <typename A>
 uint64_t Writer<A>::writeAtoms()
 {
+       // for UNIX conformance, error if file exists and is not writable
+       if ( (access(fFilePath, F_OK) == 0) && (access(fFilePath, W_OK) == -1) )
+               throwf("can't write output file: %s", fFilePath);
+
+       int permissions = 0777;
+       if ( fOptions.outputKind() == Options::kObjectFile )
+               permissions = 0666;
+       // Calling unlink first assures the file is gone so that open creates it with correct permissions
+       // It also handles the case where fFilePath file is not writable but its directory is
+       // And it means we don't have to truncate the file when done writing (in case new is smaller than old)
+       (void)unlink(fFilePath);
+       
        // try to allocate buffer for entire output file content
+       int fd = -1;
        SectionInfo* lastSection = fSegmentInfos.back()->fSections.back();
        uint64_t fileBufferSize = (lastSection->fFileOffset + lastSection->fSize + 4095) & (-4096);
        uint8_t* wholeBuffer = (uint8_t*)calloc(fileBufferSize, 1);
        uint8_t* atomBuffer = NULL;
        bool streaming = false;
        if ( wholeBuffer == NULL ) {
+               fd = open(fFilePath, O_CREAT | O_WRONLY | O_TRUNC, permissions);
+               if ( fd == -1 ) 
+                       throwf("can't open output file for writing: %s, errno=%d", fFilePath, errno);
                atomBuffer = new uint8_t[(fLargestAtomSize+4095) & (-4096)];
                streaming = true;
+               // install signal handlers to delete output file if program is killed 
+               sCleanupFile = fFilePath;
+               ::signal(SIGINT, cleanup);
+               ::signal(SIGBUS, cleanup);
+               ::signal(SIGSEGV, cleanup);
        }
        uint32_t size = 0;
        uint32_t end = 0;
-       for (std::vector<SegmentInfo*>::iterator segit = fSegmentInfos.begin(); segit != fSegmentInfos.end(); ++segit) {
-               SegmentInfo* curSegment = *segit;
-               bool isTextSeg = (strcmp(curSegment->fName, "__TEXT") == 0);
-               std::vector<SectionInfo*>& sectionInfos = curSegment->fSections;
-               for (std::vector<SectionInfo*>::iterator secit = sectionInfos.begin(); secit != sectionInfos.end(); ++secit) {
-                       SectionInfo* curSection = *secit;
-                       std::vector<ObjectFile::Atom*>& sectionAtoms = curSection->fAtoms;
-                       //printf("writing with max atom size 0x%X\n", fLargestAtomSize);
-                       //fprintf(stderr, "writing %d atoms for section %s\n", (int)sectionAtoms.size(), curSection->fSectionName);
-                       if ( ! curSection->fAllZeroFill ) {
-                               end = curSection->fFileOffset;
-                               bool needsNops = isTextSeg && (strcmp(curSection->fSectionName, "__cstring") != 0);
-                               for (std::vector<ObjectFile::Atom*>::iterator ait = sectionAtoms.begin(); ait != sectionAtoms.end(); ++ait) {
-                                       ObjectFile::Atom* atom = *ait;
-                                       if ( (atom->getDefinitionKind() != ObjectFile::Atom::kExternalDefinition)
-                                         && (atom->getDefinitionKind() != ObjectFile::Atom::kExternalWeakDefinition)
-                                         && (atom->getDefinitionKind() != ObjectFile::Atom::kAbsoluteSymbol) ) {
-                                               uint32_t fileOffset = curSection->fFileOffset + atom->getSectionOffset();
-                                               if ( fileOffset != end ) {
-                                                       if ( needsNops ) {
-                                                               // fill gaps with no-ops
-                                                               if ( streaming )
-                                                                       writeNoOps(end, fileOffset);
-                                                               else
-                                                                       copyNoOps(&wholeBuffer[end], &wholeBuffer[fileOffset]);
-                                                       }
-                                                       else if ( streaming ) {
-                                                               // zero fill gaps
-                                                               if ( (fileOffset-end) == 4 ) {
-                                                                       uint32_t zero = 0;
-                                                                       ::pwrite(fFileDescriptor, &zero, 4, end);
+       try {
+               for (std::vector<SegmentInfo*>::iterator segit = fSegmentInfos.begin(); segit != fSegmentInfos.end(); ++segit) {
+                       SegmentInfo* curSegment = *segit;
+                       bool isTextSeg = (strcmp(curSegment->fName, "__TEXT") == 0);
+                       std::vector<SectionInfo*>& sectionInfos = curSegment->fSections;
+                       for (std::vector<SectionInfo*>::iterator secit = sectionInfos.begin(); secit != sectionInfos.end(); ++secit) {
+                               SectionInfo* curSection = *secit;
+                               std::vector<ObjectFile::Atom*>& sectionAtoms = curSection->fAtoms;
+                               //printf("writing with max atom size 0x%X\n", fLargestAtomSize);
+                               //fprintf(stderr, "writing %lu atoms for section %s\n", sectionAtoms.size(), curSection->fSectionName);
+                               if ( ! curSection->fAllZeroFill ) {
+                                       end = curSection->fFileOffset;
+                                       bool needsNops = isTextSeg && (strcmp(curSection->fSectionName, "__cstring") != 0);
+                                       for (std::vector<ObjectFile::Atom*>::iterator ait = sectionAtoms.begin(); ait != sectionAtoms.end(); ++ait) {
+                                               ObjectFile::Atom* atom = *ait;
+                                               if ( (atom->getDefinitionKind() != ObjectFile::Atom::kExternalDefinition)
+                                                 && (atom->getDefinitionKind() != ObjectFile::Atom::kExternalWeakDefinition)
+                                                 && (atom->getDefinitionKind() != ObjectFile::Atom::kAbsoluteSymbol) ) {
+                                                       uint32_t fileOffset = curSection->fFileOffset + atom->getSectionOffset();
+                                                       if ( fileOffset != end ) {
+                                                               if ( needsNops ) {
+                                                                       // fill gaps with no-ops
+                                                                       if ( streaming )
+                                                                               writeNoOps(fd, end, fileOffset);
+                                                                       else
+                                                                               copyNoOps(&wholeBuffer[end], &wholeBuffer[fileOffset]);
                                                                }
-                                                               else {
-                                                                       uint8_t zero = 0x00;
-                                                                       for (uint32_t p=end; p < fileOffset; ++p)
-                                                                               ::pwrite(fFileDescriptor, &zero, 1, p);
+                                                               else if ( streaming ) {
+                                                                       // zero fill gaps
+                                                                       if ( (fileOffset-end) == 4 ) {
+                                                                               uint32_t zero = 0;
+                                                                               ::pwrite(fd, &zero, 4, end);
+                                                                       }
+                                                                       else {
+                                                                               uint8_t zero = 0x00;
+                                                                               for (uint32_t p=end; p < fileOffset; ++p)
+                                                                                       ::pwrite(fd, &zero, 1, p);
+                                                                       }
                                                                }
                                                        }
-                                               }
-                                               uint64_t atomSize = atom->getSize();
-                                               if ( streaming ) {
-                                                       if ( atomSize > fLargestAtomSize ) 
-                                                               throwf("ld64 internal error: atom \"%s\"is larger than expected 0x%X > 0x%llX", 
-                                                                                       atom->getDisplayName(), atomSize, fLargestAtomSize);
-                                               }
-                                               else {
-                                                       if ( fileOffset > fileBufferSize )
-                                                               throwf("ld64 internal error: atom \"%s\" has file offset greater thatn expceted 0x%X > 0x%llX", 
-                                                                                       atom->getDisplayName(), fileOffset, fileBufferSize);
-                                               }
-                                               uint8_t* buffer = streaming ? atomBuffer : &wholeBuffer[fileOffset];
-                                               end = fileOffset+atomSize;
-                                               // copy raw bytes
-                                               atom->copyRawContent(buffer);
-                                               // apply any fix-ups
-                                               try {
-                                                       std::vector<ObjectFile::Reference*>&  references = atom->getReferences();
-                                                       for (std::vector<ObjectFile::Reference*>::iterator it=references.begin(); it != references.end(); it++) {
-                                                               ObjectFile::Reference* ref = *it;
-                                                               if ( fOptions.outputKind() == Options::kObjectFile ) {
-                                                                       // doing ld -r
-                                                                       // skip fix-ups for undefined targets
-                                                                       if ( &(ref->getTarget()) != NULL )
-                                                                               this->fixUpReferenceRelocatable(ref, atom, buffer);
-                                                               }
-                                                               else {
-                                                                       // producing final linked image
-                                                                       this->fixUpReferenceFinal(ref, atom, buffer);
+                                                       uint64_t atomSize = atom->getSize();
+                                                       if ( streaming ) {
+                                                               if ( atomSize > fLargestAtomSize ) 
+                                                                       throwf("ld64 internal error: atom \"%s\"is larger than expected 0x%X > 0x%llX", 
+                                                                                               atom->getDisplayName(), atomSize, fLargestAtomSize);
+                                                       }
+                                                       else {
+                                                               if ( fileOffset > fileBufferSize )
+                                                                       throwf("ld64 internal error: atom \"%s\" has file offset greater thatn expceted 0x%X > 0x%llX", 
+                                                                                               atom->getDisplayName(), fileOffset, fileBufferSize);
+                                                       }
+                                                       uint8_t* buffer = streaming ? atomBuffer : &wholeBuffer[fileOffset];
+                                                       end = fileOffset+atomSize;
+                                                       // copy raw bytes
+                                                       atom->copyRawContent(buffer);
+                                                       // apply any fix-ups
+                                                       try {
+                                                               std::vector<ObjectFile::Reference*>&  references = atom->getReferences();
+                                                               for (std::vector<ObjectFile::Reference*>::iterator it=references.begin(); it != references.end(); it++) {
+                                                                       ObjectFile::Reference* ref = *it;
+                                                                       if ( fOptions.outputKind() == Options::kObjectFile ) {
+                                                                               // doing ld -r
+                                                                               // skip fix-ups for undefined targets
+                                                                               if ( &(ref->getTarget()) != NULL )
+                                                                                       this->fixUpReferenceRelocatable(ref, atom, buffer);
+                                                                       }
+                                                                       else {
+                                                                               // producing final linked image
+                                                                               this->fixUpReferenceFinal(ref, atom, buffer);
+                                                                       }
                                                                }
                                                        }
+                                                       catch (const char* msg) {
+                                                               throwf("%s in %s from %s", msg, atom->getDisplayName(), atom->getFile()->getPath());
+                                                       }
+                                                       //fprintf(stderr, "writing 0x%08X -> 0x%08X (addr=0x%llX, size=0x%llX), atom %s from %s\n", 
+                                                       //      fileOffset, end, atom->getAddress(), atom->getSize(), atom->getDisplayName(), atom->getFile()->getPath());
+                                                       if ( streaming ) {
+                                                               // write out
+                                                               ::pwrite(fd, buffer, atomSize, fileOffset);
+                                                       }
+                                                       else {
+                                                               if ( (fileOffset + atomSize) > size )
+                                                                       size = fileOffset + atomSize;
+                                                       }
                                                }
-                                               catch (const char* msg) {
-                                                       throwf("%s in %s from %s", msg, atom->getDisplayName(), atom->getFile()->getPath());
-                                               }
-                                               //fprintf(stderr, "writing 0x%08X -> 0x%08X (addr=0x%llX, size=0x%llX), atom %s from %s\n", 
-                                               //      fileOffset, end, atom->getAddress(), atom->getSize(), atom->getDisplayName(), atom->getFile()->getPath());
-                                               if ( streaming ) {
-                                                       // write out
-                                                       ::pwrite(fFileDescriptor, buffer, atomSize, fileOffset);
-                                               }
-                                               else {
-                                                       if ( (fileOffset + atomSize) > size )
-                                                               size = fileOffset + atomSize;
-                                               }
                                        }
                                }
                        }
-               }
-       }
-       
-       // update content based UUID
-       if ( fOptions.getUUIDMode() == Options::kUUIDContent ) {
-               uint8_t digest[CC_MD5_DIGEST_LENGTH];
-               if ( streaming ) {
-                       // if output file file did not fit in memory, re-read file to generate md5 hash
-                       uint32_t kMD5BufferSize = 16*1024;
-                       uint8_t* md5Buffer = (uint8_t*)::malloc(kMD5BufferSize);
-                       if ( md5Buffer != NULL ) {
-                               CC_MD5_CTX md5State;
-                               CC_MD5_Init(&md5State);
-                               ::lseek(fFileDescriptor, 0, SEEK_SET);
-                               ssize_t len;
-                               while ( (len = ::read(fFileDescriptor, md5Buffer, kMD5BufferSize)) > 0 ) 
-                                       CC_MD5_Update(&md5State, md5Buffer, len);
-                               CC_MD5_Final(digest, &md5State);
-                               ::free(md5Buffer);
+               }
+
+               // update content based UUID
+               if ( fOptions.getUUIDMode() == Options::kUUIDContent ) {
+                       uint8_t digest[CC_MD5_DIGEST_LENGTH];
+                       if ( streaming ) {
+                               // if output file file did not fit in memory, re-read file to generate md5 hash
+                               uint32_t kMD5BufferSize = 16*1024;
+                               uint8_t* md5Buffer = (uint8_t*)::malloc(kMD5BufferSize);
+                               if ( md5Buffer != NULL ) {
+                                       CC_MD5_CTX md5State;
+                                       CC_MD5_Init(&md5State);
+                                       ::lseek(fd, 0, SEEK_SET);
+                                       ssize_t len;
+                                       while ( (len = ::read(fd, md5Buffer, kMD5BufferSize)) > 0 ) 
+                                               CC_MD5_Update(&md5State, md5Buffer, len);
+                                       CC_MD5_Final(digest, &md5State);
+                                       ::free(md5Buffer);
+                               }
+                               else {
+                                       // if malloc fails, fall back to random uuid
+                                       ::uuid_generate_random(digest);
+                               }
+                               fUUIDAtom->setContent(digest);
+                               uint32_t uuidOffset = ((SectionInfo*)fUUIDAtom->getSection())->fFileOffset + fUUIDAtom->getSectionOffset();
+                               fUUIDAtom->copyRawContent(atomBuffer);
+                               ::pwrite(fd, atomBuffer, fUUIDAtom->getSize(), uuidOffset);
+                       }
+                       else {
+                               // if output file fit in memory, just genrate an md5 hash in memory
+                       #if 1
+                               // temp hack for building on Tiger
+                               CC_MD5_CTX md5State;
+                               CC_MD5_Init(&md5State);
+                               CC_MD5_Update(&md5State, wholeBuffer, size);
+                               CC_MD5_Final(digest, &md5State);
+                       #else
+                               CC_MD5(wholeBuffer, size, digest);
+                       #endif
+                               fUUIDAtom->setContent(digest);
+                               uint32_t uuidOffset = ((SectionInfo*)fUUIDAtom->getSection())->fFileOffset + fUUIDAtom->getSectionOffset();
+                               fUUIDAtom->copyRawContent(&wholeBuffer[uuidOffset]);
+                       }
+               }
+       }
+       catch (...) {
+               if ( sCleanupFile != NULL ) 
+                       ::unlink(sCleanupFile);
+               throw;
+       }
+       
+       // finish up
+       if ( streaming ) {
+               delete [] atomBuffer;
+               close(fd);
+               // restore default signal handlers
+               sCleanupFile = NULL;
+               ::signal(SIGINT, SIG_DFL);
+               ::signal(SIGBUS, SIG_DFL);
+               ::signal(SIGSEGV, SIG_DFL);
+       }
+       else {
+               // write whole output file in one chunk
+               fd = open(fFilePath, O_CREAT | O_WRONLY | O_TRUNC, permissions);
+               if ( fd == -1 ) 
+                       throwf("can't open output file for writing: %s, errno=%d", fFilePath, errno);
+               ::pwrite(fd, wholeBuffer, size, 0);
+               close(fd);
+               delete [] wholeBuffer;
+       }
+       
+       return end;
+}
+
+template <>
+void Writer<arm>::fixUpReferenceFinal(const ObjectFile::Reference* ref, const ObjectFile::Atom* inAtom, uint8_t buffer[]) const
+{
+       int64_t         displacement;
+       int64_t         baseAddr;
+       uint32_t        instruction;
+       uint32_t        newInstruction;
+       uint64_t        targetAddr = 0;
+       uint32_t        firstDisp;
+       uint32_t        nextDisp;
+       uint32_t        opcode;
+       bool            relocateableExternal = false;
+       bool            is_bl;
+       bool            is_blx;
+       bool            targetIsThumb;
+
+       if ( ref->getTargetBinding() != ObjectFile::Reference::kDontBind ) {
+               targetAddr = ref->getTarget().getAddress() + ref->getTargetOffset();
+               relocateableExternal = (relocationNeededInFinalLinkedImage(ref->getTarget()) == kRelocExternal);
+       }
+
+       uint32_t* fixUp = (uint32_t*)&buffer[ref->getFixUpOffset()];
+       switch ( (arm::ReferenceKinds)(ref->getKind()) ) {
+               case arm::kNoFixUp:
+               case arm::kFollowOn:
+               case arm::kGroupSubordinate:
+                       // do nothing
+                       break;
+               case arm::kPointerWeakImport:
+               case arm::kPointer:
+                       // If this is the lazy pointers section, then set all lazy pointers to
+                       // point to the dyld stub binding helper.
+                       if ( ((SectionInfo*)inAtom->getSection())->fAllLazyPointers 
+                         || ((SectionInfo*)inAtom->getSection())->fAllLazyDylibPointers ) {
+                               switch (ref->getTarget().getDefinitionKind()) {
+                                       case ObjectFile::Atom::kExternalDefinition:
+                                       case ObjectFile::Atom::kExternalWeakDefinition:
+                                               // prebound lazy pointer to another dylib ==> pointer contains zero
+                                               LittleEndian::set32(*fixUp, 0);
+                                               break;
+                                       case ObjectFile::Atom::kTentativeDefinition:
+                                       case ObjectFile::Atom::kRegularDefinition:
+                                       case ObjectFile::Atom::kWeakDefinition:
+                                       case ObjectFile::Atom::kAbsoluteSymbol:
+                                               // prebound lazy pointer to withing this dylib ==> pointer contains address
+                                               if ( ref->getTarget().isThumb() && (ref->getTargetOffset() == 0) )
+                                                       targetAddr |= 1;
+                                               LittleEndian::set32(*fixUp, targetAddr);
+                                               break;
+                               }
+                       }
+                       else if ( relocateableExternal ) {
+                               if ( fOptions.prebind() ) {
+                                       switch (ref->getTarget().getDefinitionKind()) {
+                                               case ObjectFile::Atom::kExternalDefinition:
+                                               case ObjectFile::Atom::kExternalWeakDefinition:
+                                                       // prebound external relocation ==> pointer contains addend
+                                                       LittleEndian::set32(*fixUp, ref->getTargetOffset());
+                                                       break;
+                                               case ObjectFile::Atom::kTentativeDefinition:
+                                               case ObjectFile::Atom::kRegularDefinition:
+                                               case ObjectFile::Atom::kWeakDefinition:
+                                                       // prebound external relocation to internal atom ==> pointer contains target address + addend
+                                                       if ( ref->getTarget().isThumb() && (ref->getTargetOffset() == 0) )
+                                                               targetAddr |= 1;
+                                                       LittleEndian::set32(*fixUp, targetAddr);
+                                                       break;
+                                               case ObjectFile::Atom::kAbsoluteSymbol:
+                                                       break;
+                                       }
+                               } 
+                               else {
+                                       // external relocation ==> pointer contains addend
+                                       LittleEndian::set32(*fixUp, ref->getTargetOffset());
+                               }
+                       }
+                       else {
+                               // pointer contains target address
+                               if ( ref->getTarget().isThumb() && (ref->getTargetOffset() == 0))
+                                       targetAddr |= 1;
+                               LittleEndian::set32(*fixUp, targetAddr);
+                       }
+                       break;
+               case arm::kPointerDiff:
+                       LittleEndian::set32(*fixUp,
+                               (ref->getTarget().getAddress() + ref->getTargetOffset()) - (ref->getFromTarget().getAddress() + ref->getFromTargetOffset()) );
+                       break;
+               case arm::kBranch24WeakImport:
+               case arm::kBranch24:
+                       displacement = targetAddr - (inAtom->getAddress() + ref->getFixUpOffset());
+                       // 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);
+                       // 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());
+                       }
+                       instruction = LittleEndian::get32(*fixUp);
+                       // Make sure we are calling arm with bl, thumb with blx
+                       is_bl = ((instruction & 0xFF000000) == 0xEB000000);
+                       is_blx = ((instruction & 0xFE000000) == 0xFA000000);
+                       if ( is_bl && ref->getTarget().isThumb() ) {
+                               uint32_t opcode = 0xFA000000;
+                               uint32_t disp = (uint32_t)(displacement >> 2) & 0x00FFFFFF;
+                               uint32_t h_bit = (uint32_t)(displacement << 23) & 0x01000000;
+                               newInstruction = opcode | h_bit | disp;
+                       } 
+                       else if ( is_blx && !ref->getTarget().isThumb() ) {
+                               uint32_t opcode = 0xEB000000;
+                               uint32_t disp = (uint32_t)(displacement >> 2) & 0x00FFFFFF;
+                               newInstruction = opcode | disp;
+                       } 
+                       else if ( !is_bl && !is_blx && ref->getTarget().isThumb() ) {
+                               throwf("don't know how to convert instruction %x referencing %s to thumb",
+                                        instruction, ref->getTarget().getDisplayName());
+                       } 
+                       else {
+                               newInstruction = (instruction & 0xFF000000) | ((uint32_t)(displacement >> 2) & 0x00FFFFFF);
+                       }
+                       LittleEndian::set32(*fixUp, newInstruction);
+                       break;
+               case arm::kThumbBranch22WeakImport:
+               case arm::kThumbBranch22:
+                       instruction = LittleEndian::get32(*fixUp);
+                       is_bl = ((instruction & 0xF8000000) == 0xF8000000);
+                       is_blx = ((instruction & 0xF8000000) == 0xE8000000);
+                       targetIsThumb = ref->getTarget().isThumb();
+                       
+                       // The pc added will be +4 from the pc
+                       baseAddr = inAtom->getAddress() + ref->getFixUpOffset() + 4;
+                       // If the target is not thumb, we will be generating a blx instruction
+                       // Since blx cannot have the low bit set, set bit[1] of the target to
+                       // bit[1] of the base address, so that the difference is a multiple of
+                       // 4 bytes.
+                       if ( !targetIsThumb ) {
+                         targetAddr &= -3ULL;
+                         targetAddr |= (baseAddr & 2LL);
+                       }
+                       displacement = targetAddr - baseAddr;
+                       
+                       // max positive displacement is 0x003FFFFE
+                       // max negative displacement is 0xFFC00000
+                       if ( (displacement > 4194302LL) || (displacement < (-4194304LL)) ) {
+                               throwf("thumb bl/blx out of range (%lld max is +/-4M) from %s in %s to %s in %s",
+                                                               displacement, inAtom->getDisplayName(), inAtom->getFile()->getPath(),
+                                                               ref->getTarget().getDisplayName(), ref->getTarget().getFile()->getPath());
+                       }
+                       // The instruction is really two instructions:
+                       // The lower 16 bits are the first instruction, which contains the first
+                       //   11 bits of the displacement.
+                       // The upper 16 bits are the second instruction, which contains the next
+                       //   11 bits of the displacement, as well as differentiating bl and blx.
+                       {
+                               firstDisp = (uint32_t)(displacement >> 12) & 0x7FF;
+                               nextDisp = (uint32_t)(displacement >> 1) & 0x7FF;
+                               if ( is_bl && !targetIsThumb ) {
+                                       opcode = 0xE800F000;
+                               } 
+                               else if ( is_blx && targetIsThumb ) {
+                                       opcode = 0xF800F000;
+                               } 
+                               else if ( !is_bl && !is_blx && !targetIsThumb ) {
+                                 throwf("don't know how to convert instruction %x referencing %s to arm",
+                                                instruction, ref->getTarget().getDisplayName());
+                               } 
+                               else {
+                                       opcode = instruction & 0xF800F800;
+                               }
+                               newInstruction = opcode | (nextDisp << 16) | firstDisp;
+                               LittleEndian::set32(*fixUp, newInstruction);
+                       }
+                       break;
+               case arm::kDtraceProbeSite:
+               case arm::kDtraceIsEnabledSite:
+                       if ( inAtom->isThumb() ) {
+                               // change 32-bit blx call site to two thumb NOPs
+                               LittleEndian::set32(*fixUp, 0x46C046C0);
+                       }
+                       else {
+                               // change call site to a NOP
+                               LittleEndian::set32(*fixUp, 0xE1A00000);
+                       }
+                       break;
+               case arm::kDtraceTypeReference:
+               case arm::kDtraceProbe:
+                       // nothing to fix up
+                       break;
+               default:
+                       throw "boom shaka laka";
+       }
+}
+
+template <>
+void Writer<arm>::fixUpReferenceRelocatable(const ObjectFile::Reference* ref, const ObjectFile::Atom* inAtom, uint8_t buffer[]) const
+{
+       int64_t         displacement;
+       uint32_t        instruction;
+       uint32_t        newInstruction;
+       uint64_t        targetAddr = 0;
+       int64_t         baseAddr;
+       uint32_t        firstDisp;
+       uint32_t        nextDisp;
+       uint32_t        opcode;
+       bool            relocateableExternal = false;
+       bool            is_bl;
+       bool            is_blx;
+       bool            targetIsThumb;
+
+       if ( ref->getTargetBinding() != ObjectFile::Reference::kDontBind ) {
+               targetAddr = ref->getTarget().getAddress() + ref->getTargetOffset();
+               relocateableExternal = this->makesExternalRelocatableReference(ref->getTarget());       
+       }
+
+       uint32_t* fixUp = (uint32_t*)&buffer[ref->getFixUpOffset()];
+       switch ( (arm::ReferenceKinds)(ref->getKind()) ) {
+               case arm::kNoFixUp:
+               case arm::kFollowOn:
+               case arm::kGroupSubordinate:
+                       // do nothing
+                       break;
+               case arm::kPointer:
+               case arm::kPointerWeakImport:
+                       {
+                       if ( ((SectionInfo*)inAtom->getSection())->fAllNonLazyPointers ) {
+                               // indirect symbol table has INDIRECT_SYMBOL_LOCAL, so we must put address in content
+                               if ( this->indirectSymbolIsLocal(ref) ) 
+                                       LittleEndian::set32(*fixUp, targetAddr);
+                               else
+                                       LittleEndian::set32(*fixUp, 0);
+                       }
+                       else if ( relocateableExternal ) {
+                               if ( fOptions.prebind() ) {
+                                       switch (ref->getTarget().getDefinitionKind()) {
+                                               case ObjectFile::Atom::kExternalDefinition:
+                                               case ObjectFile::Atom::kExternalWeakDefinition:
+                                                       // prebound external relocation ==> pointer contains addend
+                                                       LittleEndian::set32(*fixUp, ref->getTargetOffset());
+                                                       break;
+                                               case ObjectFile::Atom::kTentativeDefinition:
+                                               case ObjectFile::Atom::kRegularDefinition:
+                                               case ObjectFile::Atom::kWeakDefinition:
+                                                       // prebound external relocation to internal atom ==> pointer contains target address + addend
+                                                       LittleEndian::set32(*fixUp, targetAddr);
+                                                       break;
+                                               case ObjectFile::Atom::kAbsoluteSymbol:
+                                                       break;
+                                       }
+                               }
+                       }
+                       else {
+                               // internal relocation
+                               if ( ref->getTarget().getDefinitionKind() != ObjectFile::Atom::kTentativeDefinition ) {
+                                       // pointer contains target address
+                                       if ( ref->getTarget().isThumb() && (ref->getTargetOffset() == 0))
+                                               targetAddr |= 1;
+                                               LittleEndian::set32(*fixUp, targetAddr);
+                                       }
+                                       else {
+                                               // pointer contains addend
+                                               LittleEndian::set32(*fixUp, ref->getTargetOffset());
+                                       }
+                               }
+                       }
+                       break;
+               case arm::kPointerDiff:
+                               LittleEndian::set32(*fixUp,
+                                       (ref->getTarget().getAddress() + ref->getTargetOffset()) - (ref->getFromTarget().getAddress() + ref->getFromTargetOffset()) );
+                       break;
+               case arm::kDtraceProbeSite:
+               case arm::kDtraceIsEnabledSite:
+               case arm::kBranch24WeakImport:
+               case arm::kBranch24:
+                       displacement = targetAddr - (inAtom->getAddress() + ref->getFixUpOffset());
+                       // The pc added will be +8 from the pc
+                       displacement -= 8;
+                       // fprintf(stderr, "b/bl/blx fixup to %s at 0x%08llX, displacement = 0x%08llX\n", ref->getTarget().getDisplayName(), ref->getTarget().getAddress(), displacement);
+                       if ( relocateableExternal )  {
+                               // doing "ld -r" to an external symbol
+                               // the mach-o way of encoding this is that the bl instruction's target addr is the offset into the target
+                               displacement -= ref->getTarget().getAddress();
                        }
                        else {
-                               // if malloc fails, fall back to random uuid
-                               ::uuid_generate_random(digest);
+                               // max positive displacement is 0x007FFFFF << 2
+                               // max negative displacement is 0xFF800000 << 2
+                               if ( (displacement > 33554428LL) || (displacement < (-33554432LL)) ) {
+                                       throwf("arm 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());
+                               }
                        }
-                       fUUIDAtom->setContent(digest);
-                       uint32_t uuidOffset = ((SectionInfo*)fUUIDAtom->getSection())->fFileOffset + fUUIDAtom->getSectionOffset();
-                       fUUIDAtom->copyRawContent(atomBuffer);
-                       ::pwrite(fFileDescriptor, atomBuffer, fUUIDAtom->getSize(), uuidOffset);
-               }
-               else {
-                       // if output file fit in memory, just genrate an md5 hash in memory
-                       CC_MD5(wholeBuffer, size, digest);
-                       fUUIDAtom->setContent(digest);
-                       uint32_t uuidOffset = ((SectionInfo*)fUUIDAtom->getSection())->fFileOffset + fUUIDAtom->getSectionOffset();
-                       fUUIDAtom->copyRawContent(&wholeBuffer[uuidOffset]);
-               }
-       }
-       
-       // finish up
-       if ( streaming ) {
-               delete [] atomBuffer;
-       }
-       else {
-               // write whole output file in one chunk
-               ::pwrite(fFileDescriptor, wholeBuffer, size, 0);
-               delete [] wholeBuffer;
+                       instruction = LittleEndian::get32(*fixUp);
+                       // Make sure we are calling arm with bl, thumb with blx
+                       is_bl = ((instruction & 0xFF000000) == 0xEB000000);
+                       is_blx = ((instruction & 0xFE000000) == 0xFA000000);
+                       if ( is_bl && ref->getTarget().isThumb() ) {
+                               uint32_t opcode = 0xFA000000;
+                               uint32_t disp = (uint32_t)(displacement >> 2) & 0x00FFFFFF;
+                               uint32_t h_bit = (uint32_t)(displacement << 23) & 0x01000000;
+                               newInstruction = opcode | h_bit | disp;
+                       }
+                       else if ( is_blx && !ref->getTarget().isThumb() ) {
+                               uint32_t opcode = 0xEB000000;
+                               uint32_t disp = (uint32_t)(displacement >> 2) & 0x00FFFFFF;
+                               newInstruction = opcode | disp;
+                       } 
+                       else if ( !is_bl && !is_blx && ref->getTarget().isThumb() ) {
+                               throwf("don't know how to convert instruction %x referencing %s to thumb",
+                                        instruction, ref->getTarget().getDisplayName());
+                       } 
+                       else {
+                               newInstruction = (instruction & 0xFF000000) | ((uint32_t)(displacement >> 2) & 0x00FFFFFF);
+                       }
+                       LittleEndian::set32(*fixUp, newInstruction);
+                       break;
+               case arm::kThumbBranch22WeakImport:
+               case arm::kThumbBranch22:
+                       instruction = LittleEndian::get32(*fixUp);
+                       is_bl = ((instruction & 0xF8000000) == 0xF8000000);
+                       is_blx = ((instruction & 0xF8000000) == 0xE8000000);
+                       targetIsThumb = ref->getTarget().isThumb();
+                       
+                       // The pc added will be +4 from the pc
+                       baseAddr = inAtom->getAddress() + ref->getFixUpOffset() + 4;
+                       // If the target is not thumb, we will be generating a blx instruction
+                       // Since blx cannot have the low bit set, set bit[1] of the target to
+                       // bit[1] of the base address, so that the difference is a multiple of
+                       // 4 bytes.
+                       if (!targetIsThumb) {
+                               targetAddr &= -3ULL;
+                               targetAddr |= (baseAddr & 2LL);
+                       }
+                       displacement = targetAddr - baseAddr;
+                       
+                       //fprintf(stderr, "thumb %s fixup to %s at 0x%08llX, baseAddr = 0x%08llX, displacement = 0x%08llX, %d\n", is_blx ? "blx" : "bl",  ref->getTarget().getDisplayName(), targetAddr, baseAddr, displacement, targetIsThumb);
+                       if ( relocateableExternal )  {
+                               // doing "ld -r" to an external symbol
+                               // the mach-o way of encoding this is that the bl instruction's target addr is the offset into the target
+                               displacement -= ref->getTarget().getAddress();
+                       }
+                       else {
+                               // max positive displacement is 0x003FFFFE
+                               // max negative displacement is 0xFFC00000
+                               if ( (displacement > 4194302LL) || (displacement < (-4194304LL)) ) {
+                                       throwf("thumb bl/blx out of range (%lld max is +/-4M) from %s in %s to %s in %s",
+                                                               displacement, inAtom->getDisplayName(), inAtom->getFile()->getPath(),
+                                                               ref->getTarget().getDisplayName(), ref->getTarget().getFile()->getPath());
+                               }
+                       }
+                       // The instruction is really two instructions:
+                       // The lower 16 bits are the first instruction, which contains the first
+                       //   11 bits of the displacement.
+                       // The upper 16 bits are the second instruction, which contains the next
+                       //   11 bits of the displacement, as well as differentiating bl and blx.
+                       firstDisp = (uint32_t)(displacement >> 12) & 0x7FF;
+                       nextDisp = (uint32_t)(displacement >> 1) & 0x7FF;
+                       if ( is_bl && !targetIsThumb ) {
+                               opcode = 0xE800F000;
+                       } 
+                       else if ( is_blx && targetIsThumb ) {
+                               opcode = 0xF800F000;
+                       } 
+                       else if ( !is_bl && !is_blx && !targetIsThumb ) {
+                               throwf("don't know how to convert instruction %x referencing %s to arm",
+                                        instruction, ref->getTarget().getDisplayName());
+                       } 
+                       else {
+                               opcode = instruction & 0xF800F800;
+                       }
+                       newInstruction = opcode | (nextDisp << 16) | firstDisp;
+                       LittleEndian::set32(*fixUp, newInstruction);
+                       break;
+               case arm::kDtraceProbe:
+               case arm::kDtraceTypeReference:
+                       // nothing to fix up
+                       break;
+               default:
+                       throw "unhandled arm refernce kind";
        }
-       
-       close(fFileDescriptor);
-       return end;
 }
 
-
 template <>
 void Writer<x86>::fixUpReferenceFinal(const ObjectFile::Reference* ref, const ObjectFile::Atom* inAtom, uint8_t buffer[]) const
 {
@@ -3881,11 +4903,13 @@ void Writer<x86>::fixUpReferenceFinal(const ObjectFile::Reference* ref, const Ob
        uint8_t*  dtraceProbeSite;
        const int64_t kTwoGigLimit = 0x7FFFFFFF;
        const int64_t kSixtyFourKiloLimit = 0x7FFF;
+       const int64_t kOneTwentyEightLimit = 0x7F;
        int64_t displacement;
        x86::ReferenceKinds kind = (x86::ReferenceKinds)(ref->getKind());
        switch ( kind ) {
                case x86::kNoFixUp:
                case x86::kFollowOn:
+               case x86::kGroupSubordinate:
                        // do nothing
                        break;
                case x86::kPointerWeakImport:
@@ -3910,7 +4934,7 @@ void Writer<x86>::fixUpReferenceFinal(const ObjectFile::Reference* ref, const Ob
                                                }
                                        } 
                                        else {
-                                               // external realocation ==> pointer contains addend
+                                               // external relocation ==> pointer contains addend
                                                LittleEndian::set32(*fixUp, ref->getTargetOffset());
                                        }
                                }
@@ -3952,6 +4976,7 @@ void Writer<x86>::fixUpReferenceFinal(const ObjectFile::Reference* ref, const Ob
                case x86::kPCRel32WeakImport:
                case x86::kPCRel32:
                case x86::kPCRel16:
+               case x86::kPCRel8:
                        displacement = 0;
                        switch ( ref->getTarget().getDefinitionKind() ) {
                                case ObjectFile::Atom::kRegularDefinition:
@@ -3968,7 +4993,14 @@ void Writer<x86>::fixUpReferenceFinal(const ObjectFile::Reference* ref, const Ob
                                        displacement = (ref->getTarget().getSectionOffset() + ref->getTargetOffset()) - (inAtom->getAddress() + ref->getFixUpOffset() + 4);
                                        break;
                        }
-                       if ( kind == x86::kPCRel16 ) {
+                       if ( kind == x86::kPCRel8 ) {
+                               if ( (displacement > kOneTwentyEightLimit) || (displacement < -(kOneTwentyEightLimit)) ) {
+                                       //fprintf(stderr, "call out of range from %s in %s to %s in %s\n", this->getDisplayName(), this->getFile()->getPath(), target.getDisplayName(), target.getFile()->getPath());
+                                       throwf("rel8 out of range in %s", inAtom->getDisplayName());
+                               }
+                               *(int8_t*)fixUp = (int8_t)displacement;
+                       }
+                       else if ( kind == x86::kPCRel16 ) {
                                if ( (displacement > kSixtyFourKiloLimit) || (displacement < -(kSixtyFourKiloLimit)) ) {
                                        //fprintf(stderr, "call out of range from %s in %s to %s in %s\n", this->getDisplayName(), this->getFile()->getPath(), target.getDisplayName(), target.getFile()->getPath());
                                        throwf("rel16 out of range in %s", inAtom->getDisplayName());
@@ -3993,7 +5025,7 @@ void Writer<x86>::fixUpReferenceFinal(const ObjectFile::Reference* ref, const Ob
                                        break;
                                case ObjectFile::Atom::kExternalDefinition:
                                case ObjectFile::Atom::kExternalWeakDefinition:
-                                       // external realocation ==> pointer contains addend
+                                       // external relocation ==> pointer contains addend
                                        LittleEndian::set32(*fixUp, ref->getTargetOffset());
                                        break;
                                case ObjectFile::Atom::kAbsoluteSymbol:
@@ -4016,6 +5048,7 @@ void Writer<x86>::fixUpReferenceRelocatable(const ObjectFile::Reference* ref, co
 {
        const int64_t kTwoGigLimit = 0x7FFFFFFF;
        const int64_t kSixtyFourKiloLimit = 0x7FFF;
+       const int64_t kOneTwentyEightLimit = 0x7F;
        uint32_t* fixUp = (uint32_t*)&buffer[ref->getFixUpOffset()];
        bool isExtern = this->makesExternalRelocatableReference(ref->getTarget());      
        int64_t displacement;
@@ -4023,6 +5056,7 @@ void Writer<x86>::fixUpReferenceRelocatable(const ObjectFile::Reference* ref, co
        switch ( kind ) {
                case x86::kNoFixUp:
                case x86::kFollowOn:
+               case x86::kGroupSubordinate:
                        // do nothing
                        break;
                case x86::kPointer:
@@ -4030,7 +5064,7 @@ void Writer<x86>::fixUpReferenceRelocatable(const ObjectFile::Reference* ref, co
                case x86::kAbsolute32:
                        {
                                if ( isExtern ) {
-                                       // external realocation ==> pointer contains addend
+                                       // external relocation ==> pointer contains addend
                                        LittleEndian::set32(*fixUp, ref->getTargetOffset());
                                }
                                else if ( ((SectionInfo*)inAtom->getSection())->fAllNonLazyPointers ) {
@@ -4060,6 +5094,7 @@ void Writer<x86>::fixUpReferenceRelocatable(const ObjectFile::Reference* ref, co
                                        throwf("16-bit pointer diff out of range in %s", inAtom->getDisplayName());
                                LittleEndian::set16(*((uint16_t*)fixUp), (uint16_t)displacement);
                        break;
+               case x86::kPCRel8:
                case x86::kPCRel16:
                case x86::kPCRel32:
                case x86::kPCRel32WeakImport:
@@ -4070,7 +5105,16 @@ void Writer<x86>::fixUpReferenceRelocatable(const ObjectFile::Reference* ref, co
                                        displacement = ref->getTargetOffset() - (inAtom->getAddress() + ref->getFixUpOffset() + 4);
                                else
                                        displacement = (ref->getTarget().getAddress() + ref->getTargetOffset()) - (inAtom->getAddress() + ref->getFixUpOffset() + 4);
-                               if ( kind == x86::kPCRel16 ) {
+                               if ( kind == x86::kPCRel8 ) {
+                                       displacement += 3;
+                                       if ( (displacement > kOneTwentyEightLimit) || (displacement < -(kOneTwentyEightLimit)) ) {
+                                               //fprintf(stderr, "call out of range from %s in %s to %s in %s\n", this->getDisplayName(), this->getFile()->getPath(), target.getDisplayName(), target.getFile()->getPath());
+                                               throwf("rel8 out of range (%lld)in %s", displacement, inAtom->getDisplayName());
+                                       }
+                                       int8_t byte = (int8_t)displacement;
+                                       *((int8_t*)fixUp) = byte;
+                               }
+                               else if ( kind == x86::kPCRel16 ) {
                                        displacement += 2;
                                        if ( (displacement > kSixtyFourKiloLimit) || (displacement < -(kSixtyFourKiloLimit)) ) {
                                                //fprintf(stderr, "call out of range from %s in %s to %s in %s\n", this->getDisplayName(), this->getFile()->getPath(), target.getDisplayName(), target.getFile()->getPath());
@@ -4081,7 +5125,8 @@ void Writer<x86>::fixUpReferenceRelocatable(const ObjectFile::Reference* ref, co
                                }
                                else {
                                        if ( (displacement > kTwoGigLimit) || (displacement < (-kTwoGigLimit)) ) {
-                                               //fprintf(stderr, "call out of range from %s in %s to %s in %s\n", this->getDisplayName(), this->getFile()->getPath(), target.getDisplayName(), target.getFile()->getPath());
+                                               //fprintf(stderr, "call out of range, displacement=ox%llX, from %s in %s to %s in %s\n", displacement, 
+                                               //      inAtom->getDisplayName(), inAtom->getFile()->getPath(), ref->getTarget().getDisplayName(), ref->getTarget().getFile()->getPath());
                                                throwf("rel32 out of range in %s", inAtom->getDisplayName());
                                        }
                                        LittleEndian::set32(*fixUp, (int32_t)displacement);
@@ -4105,6 +5150,7 @@ void Writer<x86_64>::fixUpReferenceFinal(const ObjectFile::Reference* ref, const
        switch ( (x86_64::ReferenceKinds)(ref->getKind()) ) {
                case x86_64::kNoFixUp:
                case x86_64::kFollowOn:
+               case x86_64::kGroupSubordinate:
                        // do nothing
                        break;
                case x86_64::kPointerWeakImport:
@@ -4112,7 +5158,7 @@ void Writer<x86_64>::fixUpReferenceFinal(const ObjectFile::Reference* ref, const
                        {
                                //fprintf(stderr, "fixUpReferenceFinal: %s reference to %s\n", this->getDisplayName(), target.getDisplayName());
                                if ( this->relocationNeededInFinalLinkedImage(ref->getTarget()) == kRelocExternal ) {
-                                       // external realocation ==> pointer contains addend
+                                       // external relocation ==> pointer contains addend
                                        LittleEndian::set64(*fixUp, ref->getTargetOffset());
                                }
                                else {
@@ -4146,6 +5192,7 @@ void Writer<x86_64>::fixUpReferenceFinal(const ObjectFile::Reference* ref, const
                        // fall into general rel32 case
                case x86_64::kBranchPCRel32WeakImport:
                case x86_64::kBranchPCRel32:
+               case x86_64::kBranchPCRel8:
                case x86_64::kPCRel32:
                case x86_64::kPCRel32_1:
                case x86_64::kPCRel32_2:
@@ -4176,13 +5223,26 @@ void Writer<x86_64>::fixUpReferenceFinal(const ObjectFile::Reference* ref, const
                                case x86_64::kPCRel32_4:
                                        displacement -= 4;
                                        break;
+                               case x86_64::kBranchPCRel8:
+                                       displacement += 3;
+                                       break;
                        }
-                       if ( (displacement > twoGigLimit) || (displacement < (-twoGigLimit)) ) {
-                               fprintf(stderr, "call 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";
+                       if ( ref->getKind() == x86_64::kBranchPCRel8 ) {
+                               if ( (displacement > 127) || (displacement < (-128)) ) {
+                                       fprintf(stderr, "branch 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 "rel8 out of range";
+                               }
+                               *((int8_t*)fixUp) = (int8_t)displacement;
+                       }
+                       else {
+                               if ( (displacement > twoGigLimit) || (displacement < (-twoGigLimit)) ) {
+                                       fprintf(stderr, "call 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";
+                               }
+                               LittleEndian::set32(*((uint32_t*)fixUp), (int32_t)displacement);
                        }
-                       LittleEndian::set32(*((uint32_t*)fixUp), (int32_t)displacement);
                        break;
                case x86_64::kDtraceProbeSite:
                        // change call site to a NOP
@@ -4220,13 +5280,14 @@ void Writer<x86_64>::fixUpReferenceRelocatable(const ObjectFile::Reference* ref,
        switch ( (x86_64::ReferenceKinds)(ref->getKind()) ) {
                case x86_64::kNoFixUp:
                case x86_64::kFollowOn:
+               case x86_64::kGroupSubordinate:
                        // do nothing
                        break;
                case x86_64::kPointer:
                case x86_64::kPointerWeakImport:
                        {
                                if ( external ) {
-                                       // external realocation ==> pointer contains addend
+                                       // external relocation ==> pointer contains addend
                                        LittleEndian::set64(*fixUp, ref->getTargetOffset());
                                }
                                else {
@@ -4278,6 +5339,23 @@ void Writer<x86_64>::fixUpReferenceRelocatable(const ObjectFile::Reference* ref,
                        }
                        LittleEndian::set32(*((uint32_t*)fixUp), (int32_t)displacement);
                        break;
+               case x86_64::kBranchPCRel8:
+                       // turn unsigned 64-bit target offset in signed 32-bit offset, since that is what source originally had
+                       temp32 = ref->getTargetOffset();
+                       if ( external ) {
+                               // extern relocation contains addend
+                               displacement = temp32;
+                       }
+                       else {
+                               // internal relocations contain delta to target address
+                               displacement = (ref->getTarget().getAddress() + temp32) - (inAtom->getAddress() + ref->getFixUpOffset() + 1);
+                       }
+                       if ( (displacement > 127) || (displacement < (-128)) ) {
+                               //fprintf(stderr, "call out of range from %s in %s to %s in %s\n", this->getDisplayName(), this->getFile()->getPath(), target.getDisplayName(), target.getFile()->getPath());
+                               throw "rel8 out of range";
+                       }
+                       *((int8_t*)fixUp) = (int8_t)displacement;
+                       break;
                case x86_64::kPCRel32GOT:
                case x86_64::kPCRel32GOTLoad:
                case x86_64::kPCRel32GOTWeakImport:
@@ -4345,35 +5423,28 @@ void Writer<A>::fixUpReference_powerpc(const ObjectFile::Reference* ref, const O
        switch ( (typename A::ReferenceKinds)(ref->getKind()) ) {
                case A::kNoFixUp:
                case A::kFollowOn:
+               case A::kGroupSubordinate:
                        // do nothing
                        break;
                case A::kPointerWeakImport:
                case A::kPointer:
                        {
                                //fprintf(stderr, "fixUpReferenceFinal: %s reference to %s\n", this->getDisplayName(), target.getDisplayName());
-                               if ( finalLinkedImage && ((SectionInfo*)inAtom->getSection())->fAllLazyPointers ) {
-                                       if ( fOptions.prebind() ) {
-                                               switch (ref->getTarget().getDefinitionKind()) {
-                                                       case ObjectFile::Atom::kExternalDefinition:
-                                                       case ObjectFile::Atom::kExternalWeakDefinition:
-                                                               // prebound lazy pointer to another dylib ==> pointer contains zero
-                                                               P::setP(*fixUpPointer, 0);
-                                                               break;
-                                                       case ObjectFile::Atom::kTentativeDefinition:
-                                                       case ObjectFile::Atom::kRegularDefinition:
-                                                       case ObjectFile::Atom::kWeakDefinition:
-                                                               // prebound lazy pointer to withing this dylib ==> pointer contains address
-                                                               P::setP(*fixUpPointer, targetAddr);
-                                                               break;
-                                                       case ObjectFile::Atom::kAbsoluteSymbol:
-                                                               break;
-                                               }
-                                       }
-                                       else {
-                                               // lazy-symbol ==> pointer contains address of dyld_stub_binding_helper (stored in "from" target)
-                                               if ( fDyldHelper == NULL )
-                                                       throw "symbol dyld_stub_binding_helper not defined (usually in crt1.o/dylib1.o/bundle1.o)";
-                                               P::setP(*fixUpPointer, fDyldHelper->getAddress());
+                               if ( finalLinkedImage && (((SectionInfo*)inAtom->getSection())->fAllLazyPointers 
+                                                                          || ((SectionInfo*)inAtom->getSection())->fAllLazyDylibPointers) ) {
+                                       switch (ref->getTarget().getDefinitionKind()) {
+                                               case ObjectFile::Atom::kExternalDefinition:
+                                               case ObjectFile::Atom::kExternalWeakDefinition:
+                                                       // prebound lazy pointer to another dylib ==> pointer contains zero
+                                                       P::setP(*fixUpPointer, 0);
+                                                       break;
+                                               case ObjectFile::Atom::kTentativeDefinition:
+                                               case ObjectFile::Atom::kRegularDefinition:
+                                               case ObjectFile::Atom::kWeakDefinition:
+                                               case ObjectFile::Atom::kAbsoluteSymbol:
+                                                       // prebound lazy pointer to withing this dylib ==> pointer contains address
+                                                       P::setP(*fixUpPointer, targetAddr);
+                                                       break;
                                        }
                                }
                                else if ( !finalLinkedImage && ((SectionInfo*)inAtom->getSection())->fAllNonLazyPointers ) {
@@ -4402,7 +5473,7 @@ void Writer<A>::fixUpReference_powerpc(const ObjectFile::Reference* ref, const O
                                                }
                                        } 
                                        else {
-                                               // external realocation ==> pointer contains addend
+                                               // external relocation ==> pointer contains addend
                                                P::setP(*fixUpPointer, ref->getTargetOffset());
                                        }
                                }
@@ -4482,23 +5553,21 @@ void Writer<A>::fixUpReference_powerpc(const ObjectFile::Reference* ref, const O
                        break;
                case A::kBranch14:
                        {
-                               //fprintf(stderr, "bc fixup %p to %s+0x%08X == 0x%08llX\n", this, ref->getTarget().getDisplayName(), ref->getTargetOffset(), targetAddr);
                                int64_t displacement = targetAddr - (inAtom->getAddress() + ref->getFixUpOffset());
                                if ( relocateableExternal )  {
                                        // doing "ld -r" to an external symbol
                                        // the mach-o way of encoding this is that the bl instruction's target addr is the offset into the target
                                        displacement -= ref->getTarget().getAddress();
                                }
-                               else {
-                                       const int64_t b_sixtyFourKiloLimit = 0x0000FFFF;
-                                       if ( (displacement > b_sixtyFourKiloLimit) || (displacement < (-b_sixtyFourKiloLimit)) ) {
-                                               //fprintf(stderr, "bl out of range (%lld max is +/-16M) from %s in %s to %s in %s\n", displacement, this->getDisplayName(), this->getFile()->getPath(), target.getDisplayName(), target.getFile()->getPath());
-                                               throwf("bc out of range (%lld max is +/-64K) from %s in %s to %s in %s",
-                                                       displacement, inAtom->getDisplayName(), inAtom->getFile()->getPath(),
-                                                       ref->getTarget().getDisplayName(), ref->getTarget().getFile()->getPath());
-                                       }
+                               const int64_t b_sixtyFourKiloLimit = 0x0000FFFF;
+                               if ( (displacement > b_sixtyFourKiloLimit) || (displacement < (-b_sixtyFourKiloLimit)) ) {
+                                       //fprintf(stderr, "bl out of range (%lld max is +/-16M) from %s in %s to %s in %s\n", displacement, this->getDisplayName(), this->getFile()->getPath(), target.getDisplayName(), target.getFile()->getPath());
+                                       throwf("bcc out of range (%lld max is +/-64K) from %s in %s to %s in %s",
+                                               displacement, inAtom->getDisplayName(), inAtom->getFile()->getPath(),
+                                               ref->getTarget().getDisplayName(), ref->getTarget().getFile()->getPath());
                                }
-                               //fprintf(stderr, "bc fixup displacement=0x%08llX, atom.addr=0x%08llX, atom.offset=0x%08X\n", displacement, inAtom->getAddress(), (uint32_t)ref->getFixUpOffset());
+                               
+                               //fprintf(stderr, "bcc fixup displacement=0x%08llX, atom.addr=0x%08llX, atom.offset=0x%08X\n", displacement, inAtom->getAddress(), (uint32_t)ref->getFixUpOffset());
                                instruction = BigEndian::get32(*fixUp);
                                newInstruction = (instruction & 0xFFFF0003) | ((uint32_t)displacement & 0x0000FFFC);
                                //fprintf(stderr, "bc fixup: 0x%08X -> 0x%08X\n", instruction, newInstruction);
@@ -4620,12 +5689,13 @@ void Writer<A>::fixUpReference_powerpc(const ObjectFile::Reference* ref, const O
 }
 
 template <>
-bool Writer<ppc>::stubableReference(const ObjectFile::Reference* ref)
+bool Writer<ppc>::stubableReference(const ObjectFile::Atom* inAtom, const ObjectFile::Reference* ref)
 {
        uint8_t kind = ref->getKind();
        switch ( (ppc::ReferenceKinds)kind ) {
                case ppc::kNoFixUp:
                case ppc::kFollowOn:
+               case ppc::kGroupSubordinate:
                case ppc::kPointer:
                case ppc::kPointerWeakImport:
                case ppc::kPointerDiff16:
@@ -4654,7 +5724,10 @@ bool Writer<ppc>::stubableReference(const ObjectFile::Reference* ref)
                        switch ( ref->getTarget().getDefinitionKind() ) {
                                case ObjectFile::Atom::kExternalDefinition:
                                case ObjectFile::Atom::kExternalWeakDefinition:
-                                       return true;
+                                       // if the .o file this atom came from has long-branch stubs,
+                                       // then assume these instructions in a stub.
+                                       // Otherwise, these are a direct reference to something (maybe a runtime text reloc)
+                                       return ( inAtom->getFile()->hasLongBranchStubs() );
                                case ObjectFile::Atom::kTentativeDefinition:
                                case ObjectFile::Atom::kRegularDefinition:
                                case ObjectFile::Atom::kWeakDefinition:
@@ -4666,14 +5739,39 @@ bool Writer<ppc>::stubableReference(const ObjectFile::Reference* ref)
        return false;
 }
 
+template <>
+bool Writer<arm>::stubableReference(const ObjectFile::Atom* inAtom, const ObjectFile::Reference* ref)
+{
+       uint8_t kind = ref->getKind();
+       switch ( (arm::ReferenceKinds)kind ) {
+               case arm::kBranch24:
+               case arm::kBranch24WeakImport:
+               case arm::kThumbBranch22:
+               case arm::kThumbBranch22WeakImport:
+                       return true;
+               case arm::kNoFixUp:
+               case arm::kFollowOn:
+               case arm::kGroupSubordinate:
+               case arm::kPointer:
+               case arm::kPointerWeakImport:
+               case arm::kPointerDiff:
+               case arm::kDtraceProbe:
+               case arm::kDtraceProbeSite:
+               case arm::kDtraceIsEnabledSite:
+               case arm::kDtraceTypeReference:
+                       return false;
+       }
+       return false;
+}
 
 template <>
-bool Writer<ppc64>::stubableReference(const ObjectFile::Reference* ref)
+bool Writer<ppc64>::stubableReference(const ObjectFile::Atom* inAtom, const ObjectFile::Reference* ref)
 {
        uint8_t kind = ref->getKind();
        switch ( (ppc64::ReferenceKinds)kind ) {
                case ppc::kNoFixUp:
                case ppc::kFollowOn:
+               case ppc::kGroupSubordinate:
                case ppc::kPointer:
                case ppc::kPointerWeakImport:
                case ppc::kPointerDiff16:
@@ -4702,14 +5800,14 @@ bool Writer<ppc64>::stubableReference(const ObjectFile::Reference* ref)
 }
 
 template <>
-bool Writer<x86>::stubableReference(const ObjectFile::Reference* ref)
+bool Writer<x86>::stubableReference(const ObjectFile::Atom* inAtom, const ObjectFile::Reference* ref)
 {
        uint8_t kind = ref->getKind();
        return (kind == x86::kPCRel32 || kind == x86::kPCRel32WeakImport);
 }
 
 template <>
-bool Writer<x86_64>::stubableReference(const ObjectFile::Reference* ref)
+bool Writer<x86_64>::stubableReference(const ObjectFile::Atom* inAtom, const ObjectFile::Reference* ref)
 {
        uint8_t kind = ref->getKind();
        return (kind == x86_64::kBranchPCRel32 || kind == x86_64::kBranchPCRel32WeakImport);
@@ -4747,7 +5845,12 @@ bool Writer<x86_64>::weakImportReferenceKind(uint8_t kind)
        return false;
 }
 
-
+template <>
+bool Writer<arm>::weakImportReferenceKind(uint8_t kind)
+{
+       return (kind == arm::kBranch24WeakImport || kind == arm::kThumbBranch22WeakImport ||
+            kind == arm::kPointerWeakImport);
+}
 
 template <>
 bool Writer<ppc>::GOTReferenceKind(uint8_t kind)
@@ -4780,6 +5883,12 @@ bool Writer<x86_64>::GOTReferenceKind(uint8_t kind)
        return false;
 }
 
+template <>
+bool Writer<arm>::GOTReferenceKind(uint8_t kind)
+{
+       return false;
+}
+
 template <>
 bool Writer<ppc>::optimizableGOTReferenceKind(uint8_t kind)
 {
@@ -4809,7 +5918,11 @@ bool Writer<x86_64>::optimizableGOTReferenceKind(uint8_t kind)
        return false;
 }
 
-
+template <>
+bool Writer<arm>::optimizableGOTReferenceKind(uint8_t kind)
+{
+       return false;
+}
 
 // 64-bit architectures never need module table, 32-bit sometimes do for backwards compatiblity
 template <typename A> bool Writer<A>::needsModuleTable() {return fOptions.needsModuleTable(); }
@@ -4851,24 +5964,44 @@ void Writer<A>::optimizeDylibReferences()
                }
        }
        // renumber ordinals (depends on iterator walking in ordinal order)
+       // all LC_LAZY_LOAD_DYLIB load commands must have highest ordinals
        uint32_t newOrdinal = 0;
        for (std::map<uint32_t, ObjectFile::Reader*>::iterator it = ordinalToReader.begin(); it != ordinalToReader.end(); ++it) {
-               if ( it->first <= fLibraryToOrdinal.size() )
-                       fLibraryToOrdinal[it->second] = ++newOrdinal;
+               if ( it->first <= fLibraryToOrdinal.size() ) {
+                       if ( ! it->second->isLazyLoadedDylib() )
+                               fLibraryToOrdinal[it->second] = ++newOrdinal;
+               }
+       }
+       for (std::map<uint32_t, ObjectFile::Reader*>::iterator it = ordinalToReader.begin(); it != ordinalToReader.end(); ++it) {
+               if ( it->first <= fLibraryToOrdinal.size() ) {
+                       if ( it->second->isLazyLoadedDylib() ) {
+                               fLibraryToOrdinal[it->second] = ++newOrdinal;
+                       }
+               }
        }
+       
+       // <rdar://problem/5504954> linker does not error when dylib ordinal exceeds 250
+       if ( (newOrdinal >= MAX_LIBRARY_ORDINAL) && (fOptions.nameSpace() == Options::kTwoLevelNameSpace) )
+               throwf("two level namespace mach-o files can link with at most %d dylibs, this link would use %d dylibs", MAX_LIBRARY_ORDINAL, newOrdinal);
 
        // add aliases (e.g. -lm points to libSystem.dylib)
        for (std::map<ObjectFile::Reader*, ObjectFile::Reader*>::iterator it = readerAliases.begin(); it != readerAliases.end(); ++it) {
                fLibraryToOrdinal[it->first] = fLibraryToOrdinal[it->second];
        }
 
-       // fprintf(stderr, "new ordinals table:\n");
+       //fprintf(stderr, "new ordinals table:\n");
        //for (std::map<class ObjectFile::Reader*, uint32_t>::iterator it = fLibraryToOrdinal.begin(); it != fLibraryToOrdinal.end(); ++it) {
        //      fprintf(stderr, "%u <== %p/%s\n", it->second, it->first, it->first->getPath());
        //}
 }
 
 
+template <>
+void Writer<arm>::scanForAbsoluteReferences()
+{
+       // arm codegen never has absolute references.  FIXME: Is this correct?
+}
+
 template <>
 void Writer<x86_64>::scanForAbsoluteReferences()
 {
@@ -4878,8 +6011,8 @@ void Writer<x86_64>::scanForAbsoluteReferences()
 template <>
 void  Writer<x86>::scanForAbsoluteReferences()
 {
-       // when linking -pie verify there are no absolute addressing
-       if ( fOptions.positionIndependentExecutable() ) {
+       // when linking -pie verify there are no absolute addressing, unless -read_only_relocs is also used
+       if ( fOptions.positionIndependentExecutable() && !fOptions.allowTextRelocs() ) {
                for (std::vector<ObjectFile::Atom*>::iterator it=fAllAtoms->begin(); it != fAllAtoms->end(); it++) {
                        ObjectFile::Atom* atom = *it;
                        std::vector<ObjectFile::Reference*>&  references = atom->getReferences();
@@ -4887,7 +6020,7 @@ void  Writer<x86>::scanForAbsoluteReferences()
                                ObjectFile::Reference* ref = *rit;
                                switch (ref->getKind()) {
                                        case x86::kAbsolute32:
-                                               throwf("cannot link -pie: -mdynamic-no-pic codegen found in %s from %s\n", atom->getDisplayName(), atom->getFile()->getPath());
+                                               throwf("cannot link -pie: -mdynamic-no-pic codegen found in %s from %s", atom->getDisplayName(), atom->getFile()->getPath());
                                                return;
                                }
                        }
@@ -4898,8 +6031,8 @@ void  Writer<x86>::scanForAbsoluteReferences()
 template <>
 void  Writer<ppc>::scanForAbsoluteReferences()
 {
-       // when linking -pie verify there are no absolute addressing
-       if ( fOptions.positionIndependentExecutable() ) {
+       // when linking -pie verify there are no absolute addressing, unless -read_only_relocs is also used
+       if ( fOptions.positionIndependentExecutable()  && !fOptions.allowTextRelocs() ) {
                for (std::vector<ObjectFile::Atom*>::iterator it=fAllAtoms->begin(); it != fAllAtoms->end(); it++) {
                        ObjectFile::Atom* atom = *it;
                        std::vector<ObjectFile::Reference*>&  references = atom->getReferences();
@@ -4910,7 +6043,7 @@ void  Writer<ppc>::scanForAbsoluteReferences()
                                        case ppc::kAbsLow14:
                                        case ppc::kAbsHigh16:
                                        case ppc::kAbsHigh16AddLow:
-                                               throwf("cannot link -pie: -mdynamic-no-pic codegen found in %s from %s\n", atom->getDisplayName(), atom->getFile()->getPath());
+                                               throwf("cannot link -pie: -mdynamic-no-pic codegen found in %s from %s", atom->getDisplayName(), atom->getFile()->getPath());
                                                return;
                                }
                        }
@@ -4965,7 +6098,7 @@ void Writer<x86>::insertDummyStubs()
                        case 25:// stub would occupy 0x7D->0x82
                        case 38:// stub would occupy 0xBE->0xC3
                        case 51:// stub would occupy 0xFF->0x04
-                               betterStubs.push_back(new StubAtom<x86>(*this, *((ObjectFile::Atom*)NULL))); //pad with dummy stub
+                               betterStubs.push_back(new StubAtom<x86>(*this, *((ObjectFile::Atom*)NULL), false)); //pad with dummy stub
                                break;
                }
                betterStubs.push_back(*it);
@@ -5008,6 +6141,17 @@ void Writer<A>::synthesizeStubs()
                                        if ( (target.getDefinitionKind() == ObjectFile::Atom::kExternalDefinition)
                                                || (target.getDefinitionKind() == ObjectFile::Atom::kExternalWeakDefinition) ) {
                                                bool weakImport = this->weakImportReferenceKind(ref->getKind());
+                                               // <rdar://problem/5633081> Obj-C Symbols in Leopard Can't Be Weak Linked
+                                               // dyld in Mac OS X 10.3 and earlier need N_WEAK_REF bit set on undefines to objc symbols
+                                               // in dylibs that are weakly linked.  
+                                               if ( (ref->getKind() == A::kNoFixUp) && (strncmp(target.getName(), ".objc_class_name_", 17) == 0) ) {
+                                                       typename std::map<class ObjectFile::Reader*, class DylibLoadCommandsAtom<A>* >::iterator pos;
+                                                       pos = fLibraryToLoadCommand.find(target.getFile());
+                                                       if ( pos != fLibraryToLoadCommand.end() ) {
+                                                               if ( pos->second->linkedWeak() )
+                                                                       weakImport = true;
+                                                       }
+                                               }
                                                std::map<const ObjectFile::Atom*,bool>::iterator pos = fWeakImportMap.find(&target);
                                                if ( pos == fWeakImportMap.end() ) {
                                                        // target not in fWeakImportMap, so add
@@ -5029,15 +6173,33 @@ void Writer<A>::synthesizeStubs()
                                                                }
                                                        }
                                                }
+                                               // update if we use a weak_import or a strong import from this dylib
+                                               if ( fWeakImportMap[&target] )
+                                                       fDylibReadersWithWeakImports.insert(target.getFile());
+                                               else
+                                                       fDylibReadersWithNonWeakImports.insert(target.getFile());
                                        }
                                        // create stubs as needed
-                                       if ( this->stubableReference(ref) 
+                                       if ( this->stubableReference(atom, ref) 
                                                && (ref->getTargetOffset() == 0)
                                                && this->relocationNeededInFinalLinkedImage(target) == kRelocExternal ) {
                                                ObjectFile::Atom* stub = NULL;
                                                std::map<const ObjectFile::Atom*,ObjectFile::Atom*>::iterator pos = fStubsMap.find(&target);
                                                if ( pos == fStubsMap.end() ) {
-                                                       stub = new StubAtom<A>(*this, target);
+                                                       bool forLazyDylib = false;
+                                                       switch ( target.getDefinitionKind() ) {
+                                                               case ObjectFile::Atom::kRegularDefinition:
+                                                               case ObjectFile::Atom::kWeakDefinition:
+                                                               case ObjectFile::Atom::kAbsoluteSymbol:
+                                                               case ObjectFile::Atom::kTentativeDefinition:
+                                                                       break;
+                                                               case ObjectFile::Atom::kExternalDefinition:
+                                                               case ObjectFile::Atom::kExternalWeakDefinition:
+                                                                       if ( target.getFile()->isLazyLoadedDylib() )
+                                                                               forLazyDylib = true;
+                                                                       break;
+                                                       }
+                                                       stub = new StubAtom<A>(*this, target, forLazyDylib);
                                                        fStubsMap[&target] = stub;
                                                }
                                                else {
@@ -5046,6 +6208,11 @@ void Writer<A>::synthesizeStubs()
                                                // alter reference to use stub instead
                                                ref->setTarget(*stub, 0);
                                        }
+                                       else if ( fOptions.usingLazyDylibLinking() && target.getFile()->isLazyLoadedDylib() ) {
+                                               throwf("illegal reference to %s in lazy loaded dylib from %s in %s", 
+                                                               target.getDisplayName(), atom->getDisplayName(), 
+                                                               atom->getFile()->getPath());
+                                       }
                                        // create GOT slots (non-lazy pointers) as needed
                                        else if ( this->GOTReferenceKind(ref->getKind()) ) {
                                                // 
@@ -5084,51 +6251,90 @@ void Writer<A>::synthesizeStubs()
        // sort stubs
        std::sort(fAllSynthesizedStubs.begin(), fAllSynthesizedStubs.end(), AtomByNameSorter());
 
-       // add dummy stubs (x86 only)
-       this->insertDummyStubs();
+       // add dummy fast stubs (x86 only)
+       if ( !fOptions.slowx86Stubs() ) 
+               this->insertDummyStubs();
 
        // sort lazy pointers
        std::sort(fAllSynthesizedLazyPointers.begin(), fAllSynthesizedLazyPointers.end(), AtomByNameSorter());
+       std::sort(fAllSynthesizedLazyDylibPointers.begin(), fAllSynthesizedLazyDylibPointers.end(), AtomByNameSorter());
+
 
        // add stubs to fAllAtoms
        if ( fAllSynthesizedStubs.size() != 0 ) {
-               std::vector<ObjectFile::Atom*>* stubs = (std::vector<ObjectFile::Atom*>*)&fAllSynthesizedStubs;
-               std::vector<ObjectFile::Atom*> mergedStubs;
-               if ( fAllSynthesizedStubHelpers.size() != 0 ) {
-                       // when we have stubs and helpers, insert both into fAllAtoms
-                       mergedStubs.insert(mergedStubs.end(), fAllSynthesizedStubs.begin(), fAllSynthesizedStubs.end());
-                       mergedStubs.insert(mergedStubs.end(), fAllSynthesizedStubHelpers.begin(), fAllSynthesizedStubHelpers.end());
-                       stubs = &mergedStubs;
+               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 ) {
-                               // HACK HACK for i386 where stubs are not in _TEXT segment
-                               if ( strcmp(fAllSynthesizedStubs[0]->getSegment().getName(), "__IMPORT") == 0 ) {
+                               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, fAllSynthesizedStubs.begin(), fAllSynthesizedStubs.end());
+                                               fAllAtoms->insert(it, importStubs.begin(), importStubs.end());
                                                break;
                                        }
+                                       curSection = nextSection;
                                }
-                               else {
-                                       if ( (prevAtom != NULL) && (strcmp(prevAtom->getSectionName(), "__text") == 0) ) {
-                                               // found end of __text section, insert stubs here
-                                               fAllAtoms->insert(it, stubs->begin(), stubs->end());
-                                               break;
-                                       }
+                               prevAtom = atom;
+                       }
+               }
+       }
+
+
+       // 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) ) {
+                                       // 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;
@@ -5296,6 +6502,8 @@ void Writer<A>::partitionIntoSections()
                                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) )
@@ -5310,13 +6518,17 @@ void Writer<A>::partitionIntoSections()
                                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
                        }
                        curSection = atom->getSection();
-                       if ( currentSectionInfo->fAllNonLazyPointers || currentSectionInfo->fAllLazyPointers 
-                               || currentSectionInfo->fAllStubs || currentSectionInfo->fAllStubs ) {
+                       if ( currentSectionInfo->fAllNonLazyPointers || currentSectionInfo->fAllLazyPointers || currentSectionInfo->fAllLazyDylibPointers
+                               || currentSectionInfo->fAllStubs || currentSectionInfo->fAllSelfModifyingStubs ) {
                                        fSymbolTableCommands->needDynamicTable();
                                }
                }
@@ -5402,6 +6614,13 @@ bool Writer<x86_64>::addBranchIslands()
        return false;
 }
 
+template <>
+bool Writer<arm>::addBranchIslands()
+{
+       if ( fLoadCommandsSegment->fSize > 16000000 )
+               throw "arm branch islands unimplemented"; // FIXME: implement this
+       return false;
+}
 
 template <>
 bool Writer<ppc>::isBranch24Reference(uint8_t kind)
@@ -5469,6 +6688,7 @@ bool Writer<A>::addPPCBranchIslands()
                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);
 
                // create islands for branch references that are out of range
                for (std::vector<ObjectFile::Atom*>::iterator it=fAllAtoms->begin(); it != fAllAtoms->end(); it++) {
@@ -5489,8 +6709,8 @@ bool Writer<A>::addPPCBranchIslands()
                                                uint64_t nextTargetOffset = ref->getTargetOffset();
                                                for (int i=kIslandRegionsCount-1; i >=0 ; --i) {
                                                        AtomToIsland* region = &regionsMap[i];
-                                                       int64_t islandRegionAddr = kBetweenRegions * (i+1);
-                                                       if ( (srcAddr < islandRegionAddr) && (islandRegionAddr <= dstAddr) ) {
+                                                       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);
@@ -5508,7 +6728,7 @@ bool Writer<A>::addPPCBranchIslands()
                                                                }
                                                        }
                                                }
-                                               if (log) fprintf(stderr, "using island %s for %s\n", nextTarget->getDisplayName(), atom->getDisplayName());
+                                               if (log) fprintf(stderr, "using island %s for branch to %s from %s\n", nextTarget->getDisplayName(), target.getDisplayName(), atom->getDisplayName());
                                                ref->setTarget(*nextTarget, nextTargetOffset);
                                        }
                                        else if ( displacement < (-kFifteenMegLimit) ) {
@@ -5548,17 +6768,16 @@ bool Writer<A>::addPPCBranchIslands()
                        if ( log ) fprintf(stderr, "ld: %u branch islands required in %u regions\n", islandCount, kIslandRegionsCount);
                        std::vector<ObjectFile::Atom*> newAtomList;
                        newAtomList.reserve(textSection->fAtoms.size()+islandCount);
-                       uint64_t islandRegionAddr = kBetweenRegions;
+                       uint64_t islandRegionAddr = kBetweenRegions + textSection->getBaseAddress();
                        uint64_t textSectionAlignment = (1 << textSection->fAlignment);
                        int regionIndex = 0;
                        uint64_t atomSlide = 0;
                        uint64_t sectionOffset = 0;
                        for (std::vector<ObjectFile::Atom*>::iterator it=textSection->fAtoms.begin(); it != textSection->fAtoms.end(); it++) {
                                ObjectFile::Atom* atom = *it;
-                               newAtomList.push_back(atom);
                                if ( atom->getAddress() > islandRegionAddr ) {
-                                       uint64_t islandStartOffset = atom->getSectionOffset();
-                                       sectionOffset = islandStartOffset + atomSlide;
+                                       uint64_t islandStartOffset = atom->getSectionOffset() + atomSlide;
+                                       sectionOffset = islandStartOffset;
                                        std::vector<ObjectFile::Atom*>* regionIslands = &regionsIslands[regionIndex];
                                        for (std::vector<ObjectFile::Atom*>::iterator rit=regionIslands->begin(); rit != regionIslands->end(); rit++) {
                                                ObjectFile::Atom* islandAtom = *rit;
@@ -5573,6 +6792,7 @@ bool Writer<A>::addPPCBranchIslands()
                                        uint64_t islandRegionAlignmentBlocks = (sectionOffset - islandStartOffset + textSectionAlignment - 1) / textSectionAlignment;
                                        atomSlide += (islandRegionAlignmentBlocks * textSectionAlignment);
                                }
+                               newAtomList.push_back(atom);
                                if ( atomSlide != 0 )
                                        atom->setSectionOffset(atom->getSectionOffset()+atomSlide);
                        }
@@ -5639,6 +6859,11 @@ void Writer<A>::adjustLoadCommandsAndPadding()
                // mach-o .o 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 - (totalSizeOfHeaderAndLoadCommands % 4096);
+               fEncryptionLoadCommand->setStartEncryptionOffset(totalSizeOfHeaderAndLoadCommands+paddingSize);
+       }
        else {
                // work backwards from end of segment and lay out sections so that extra room goes to padding atom
                uint64_t addr = 0;
@@ -5746,6 +6971,7 @@ void Writer<A>::assignFileOffsets()
                        // update section info
                        curSection->fFileOffset = fileOffset;
                        curSection->setBaseAddress(address);
+                       //fprintf(stderr, "%s %s %llX\n", curSegment->fName, curSection->fSectionName, address);
 
                        // keep track of trailing zero fill sections
                        if ( curSection->fAllZeroFill && (firstZeroFillSection == NULL) )
@@ -5830,6 +7056,17 @@ void Writer<A>::assignFileOffsets()
                }
        }
        
+       // record size of encrypted part of __TEXT segment
+       if ( fOptions.makeEncryptable() ) {
+               for (std::vector<SegmentInfo*>::iterator segit = fSegmentInfos.begin(); segit != fSegmentInfos.end(); ++segit) {
+                       SegmentInfo* curSegment = *segit;
+                       if ( strcmp(curSegment->fName, "__TEXT") == 0 ) {
+                               fEncryptionLoadCommand->setEndEncryptionOffset(curSegment->fFileSize);
+                               break;
+                       }
+               }
+       }
+
 }
 
 template <typename A>
@@ -6068,20 +7305,7 @@ void MachHeaderAtom<ppc>::setHeaderInfo(macho_header<ppc::P>& header) const
 {
        header.set_magic(MH_MAGIC);
        header.set_cputype(CPU_TYPE_POWERPC);
-       switch ( fWriter.fCpuConstraint ) {
-               case ObjectFile::Reader::kCpuAny:
-                       header.set_cpusubtype(CPU_SUBTYPE_POWERPC_ALL);
-                       break;
-               case ObjectFile::Reader::kCpuG3:
-                       header.set_cpusubtype(CPU_SUBTYPE_POWERPC_750);
-                       break;
-               case ObjectFile::Reader::kCpuG4:
-                       header.set_cpusubtype(CPU_SUBTYPE_POWERPC_7400);
-                       break;
-               case ObjectFile::Reader::kCpuG5:
-                       header.set_cpusubtype(CPU_SUBTYPE_POWERPC_970);
-                       break;
-       }
+    header.set_cpusubtype(fWriter.fCpuConstraint);
 }
 
 template <>
@@ -6116,6 +7340,13 @@ void MachHeaderAtom<x86_64>::setHeaderInfo(macho_header<x86_64::P>& header) cons
        header.set_reserved(0);
 }
 
+template <>
+void MachHeaderAtom<arm>::setHeaderInfo(macho_header<arm::P>& header) const
+{
+       header.set_magic(MH_MAGIC);
+       header.set_cputype(CPU_TYPE_ARM);
+       header.set_cpusubtype(fWriter.fCpuConstraint);
+}
 
 template <typename A>
 CustomStackAtom<A>::CustomStackAtom(Writer<A>& writer)
@@ -6128,30 +7359,11 @@ CustomStackAtom<A>::CustomStackAtom(Writer<A>& writer)
 }
 
 
-template <>
-bool CustomStackAtom<ppc>::stackGrowsDown()
-{
-       return true;
-}
-
-template <>
-bool CustomStackAtom<ppc64>::stackGrowsDown()
-{
-       return true;
-}
-
-template <>
-bool CustomStackAtom<x86>::stackGrowsDown()
-{
-       return true;
-}
-
-template <>
-bool CustomStackAtom<x86_64>::stackGrowsDown()
-{
-       return true;
-}
-
+template <> bool CustomStackAtom<ppc>::stackGrowsDown()    { return true; }
+template <> bool CustomStackAtom<ppc64>::stackGrowsDown()  { return true; }
+template <> bool CustomStackAtom<x86>::stackGrowsDown()    { return true; }
+template <> bool CustomStackAtom<x86_64>::stackGrowsDown() { return true; }
+template <> bool CustomStackAtom<arm>::stackGrowsDown()    { return true; }
 
 template <typename A>
 void SegmentLoadCommandsAtom<A>::computeSize()
@@ -6200,6 +7412,12 @@ uint64_t LoadCommandAtom<x86_64>::alignedSize(uint64_t size)
        return ((size+7) & (-8));       // 8-byte align all load commands for 64-bit mach-o
 }
 
+template <>
+uint64_t LoadCommandAtom<arm>::alignedSize(uint64_t size)
+{
+       return ((size+3) & (-4));       // 4-byte align all load commands for 32-bit mach-o
+}
+
 template <typename A>
 void SegmentLoadCommandsAtom<A>::copyRawContent(uint8_t buffer[]) const
 {
@@ -6255,6 +7473,10 @@ void SegmentLoadCommandsAtom<A>::copyRawContent(uint8_t buffer[]) const
                                        sect->set_flags(S_LAZY_SYMBOL_POINTERS);
                                        sect->set_reserved1(sectInfo->fIndirectSymbolOffset);
                                }
+                               else if ( sectInfo->fAllLazyDylibPointers ) {
+                                       sect->set_flags(S_LAZY_DYLIB_SYMBOL_POINTERS);
+                                       sect->set_reserved1(sectInfo->fIndirectSymbolOffset);
+                               }
                                else if ( sectInfo->fAllNonLazyPointers ) {
                                        sect->set_flags(S_NON_LAZY_SYMBOL_POINTERS);
                                        sect->set_reserved1(sectInfo->fIndirectSymbolOffset);
@@ -6302,6 +7524,9 @@ void SegmentLoadCommandsAtom<A>::copyRawContent(uint8_t buffer[]) const
                                else if ( (strcmp(sectInfo->fSectionName, "__message_refs") == 0) && (strcmp(sectInfo->fSegmentName, "__OBJC") == 0) ) {
                                        sect->set_flags(S_LITERAL_POINTERS);
                                }
+                               else if ( (strcmp(sectInfo->fSectionName, "__cls_refs") == 0) && (strcmp(sectInfo->fSegmentName, "__OBJC") == 0) ) {
+                                       sect->set_flags(S_LITERAL_POINTERS);
+                               }
                                else if ( (strncmp(sectInfo->fSectionName, "__dof_", 6) == 0) && (strcmp(sectInfo->fSegmentName, "__TEXT") == 0) ) {
                                        sect->set_flags(S_DTRACE_DOF);
                                }
@@ -6310,6 +7535,10 @@ void SegmentLoadCommandsAtom<A>::copyRawContent(uint8_t buffer[]) const
                                }
                                else if ( (strncmp(sectInfo->fSectionName, "__text", 6) == 0) && (strcmp(sectInfo->fSegmentName, "__TEXT") == 0) ) {
                                        sect->set_flags(S_REGULAR | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS);
+                                       if ( sectInfo->fHasTextLocalRelocs )
+                                               sect->set_flags(sect->flags() | S_ATTR_LOC_RELOC);
+                                       if ( sectInfo->fHasTextExternalRelocs )
+                                               sect->set_flags(sect->flags() | S_ATTR_EXT_RELOC);
                                }
                        }
                }
@@ -6472,7 +7701,12 @@ void DylibLoadCommandsAtom<A>::copyRawContent(uint8_t buffer[]) const
        bzero(buffer, size);
        const char* path = fInfo.reader->getInstallPath();
        macho_dylib_command<P>* cmd = (macho_dylib_command<P>*)buffer;
-       if ( fInfo.options.fWeakImport )
+       // <rdar://problem/5529626> If only weak_import symbols are used, linker should use LD_LOAD_WEAK_DYLIB
+       bool autoWeakLoadDylib = ( (fWriter.fDylibReadersWithWeakImports.count(fInfo.reader) > 0) 
+                                                       && (fWriter.fDylibReadersWithNonWeakImports.count(fInfo.reader) == 0) );
+       if ( fInfo.options.fLazyLoad )
+               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) )
                cmd->set_cmd(LC_REEXPORT_DYLIB);
@@ -6514,6 +7748,8 @@ template <typename A>
 void RoutinesLoadCommandsAtom<A>::copyRawContent(uint8_t buffer[]) const
 {
        uint64_t initAddr = fWriter.getAtomLoadAddress(fWriter.fEntryPoint);
+  if (fWriter.fEntryPoint->isThumb())
+    initAddr |= 1ULL;
        bzero(buffer, sizeof(macho_routines_command<P>));
        macho_routines_command<P>* cmd = (macho_routines_command<P>*)buffer;
        cmd->set_cmd(macho_routines_command<P>::CMD);
@@ -6639,6 +7875,13 @@ uint64_t ThreadsLoadCommandsAtom<x86_64>::getSize() const
        return this->alignedSize(16 + x86_THREAD_STATE64_COUNT * 4); 
 }
 
+// We should be picking it up from a header
+template <>
+uint64_t ThreadsLoadCommandsAtom<arm>::getSize() const
+{
+       return this->alignedSize(16 + 17 * 4); // base size + ARM_THREAD_STATE_COUNT * 4
+}
+
 template <>
 void ThreadsLoadCommandsAtom<ppc>::copyRawContent(uint8_t buffer[]) const
 {
@@ -6688,7 +7931,6 @@ void ThreadsLoadCommandsAtom<x86>::copyRawContent(uint8_t buffer[]) const
                cmd->set_thread_register(7, fWriter.fOptions.customStackAddr());        // esp
 }
 
-
 template <>
 void ThreadsLoadCommandsAtom<x86_64>::copyRawContent(uint8_t buffer[]) const
 {
@@ -6705,6 +7947,21 @@ void ThreadsLoadCommandsAtom<x86_64>::copyRawContent(uint8_t buffer[]) const
                cmd->set_thread_register(7, fWriter.fOptions.customStackAddr());        // uesp
 }
 
+template <>
+void ThreadsLoadCommandsAtom<arm>::copyRawContent(uint8_t buffer[]) const
+{
+       uint64_t size = this->getSize();
+       uint64_t start = fWriter.getAtomLoadAddress(fWriter.fEntryPoint);
+       bzero(buffer, size);
+       macho_thread_command<arm::P>* cmd = (macho_thread_command<arm::P>*)buffer;
+       cmd->set_cmd(LC_UNIXTHREAD);
+       cmd->set_cmdsize(size);
+       cmd->set_flavor(1);                     
+       cmd->set_count(17);     
+       cmd->set_thread_register(15, start);            // pc
+       if ( fWriter.fOptions.hasCustomStack() )
+               cmd->set_thread_register(13, fWriter.fOptions.customStackAddr());       // FIXME: sp?
+}
 
 template <typename A>
 uint64_t RPathLoadCommandsAtom<A>::getSize() const
@@ -6725,6 +7982,22 @@ void RPathLoadCommandsAtom<A>::copyRawContent(uint8_t buffer[]) const
 }
 
 
+
+template <typename A>
+void EncryptionLoadCommandsAtom<A>::copyRawContent(uint8_t buffer[]) const
+{
+       uint64_t size = this->getSize();
+       bzero(buffer, size);
+       macho_encryption_info_command<P>* cmd = (macho_encryption_info_command<P>*)buffer;
+       cmd->set_cmd(LC_ENCRYPTION_INFO);
+       cmd->set_cmdsize(this->getSize());
+       cmd->set_cryptoff(fStartOffset);
+       cmd->set_cryptsize(fEndOffset-fStartOffset);
+       cmd->set_cryptid(0);
+}
+
+
+
 template <typename A>
 void LoadCommandsPaddingAtom<A>::copyRawContent(uint8_t buffer[]) const
 {
@@ -7196,6 +8469,7 @@ void ObjCInfoAtom<A>::copyRawContent(uint8_t buffer[]) const
 // objc info section is in a different segment and section for 32 vs 64 bit runtimes
 template <> const char* ObjCInfoAtom<ppc>::getSectionName()    const { return "__image_info"; }
 template <> const char* ObjCInfoAtom<x86>::getSectionName()    const { return "__image_info"; }
+template <> const char* ObjCInfoAtom<arm>::getSectionName()    const { return "__objc_imageinfo"; }
 template <> const char* ObjCInfoAtom<ppc64>::getSectionName()  const { return "__objc_imageinfo"; }
 template <> const char* ObjCInfoAtom<x86_64>::getSectionName() const { return "__objc_imageinfo"; }
 
@@ -7203,7 +8477,7 @@ template <> Segment& ObjCInfoAtom<ppc>::getInfoSegment()    const { return Segme
 template <> Segment& ObjCInfoAtom<x86>::getInfoSegment()    const { return Segment::fgObjCSegment; }
 template <> Segment& ObjCInfoAtom<ppc64>::getInfoSegment()  const { return Segment::fgDataSegment; }
 template <> Segment& ObjCInfoAtom<x86_64>::getInfoSegment() const { return Segment::fgDataSegment; }
-
+template <> Segment& ObjCInfoAtom<arm>::getInfoSegment()    const { return Segment::fgDataSegment; }
 
 
 }; // namespace executable
old mode 100644 (file)
new mode 100755 (executable)
index ce9801a..b104dda
 #include <sys/mman.h>
 #include <fcntl.h>
 #include <fcntl.h>
-#include <mach-o/loader.h>
-#include <mach-o/fat.h>
-#include <mach-o/stab.h>
 
 #include "MachOReaderRelocatable.hpp"
+#include "LTOReader.hpp"
 
 static bool                    sDumpContent= true;
 static bool                    sDumpStabs      = false;
 static bool                    sSort           = true;
+static bool                    sNMmode         = false;
 static cpu_type_t      sPreferredArch = CPU_TYPE_POWERPC64;
 static const char* sMatchName;
 static int sPrintRestrict;
@@ -56,6 +55,16 @@ void throwf(const char* format, ...)
        throw t;
 }
 
+void warning(const char* format, ...)
+{
+       va_list list;
+       fprintf(stderr, "warning: ");
+       va_start(list, format);
+       vfprintf(stderr, format, list);
+       va_end(list);
+       fprintf(stderr, "\n");
+}
+
 static void dumpStabs(std::vector<ObjectFile::Reader::Stab>* stabs)
 {
        // debug info
@@ -154,6 +163,49 @@ static void dumpStabs(std::vector<ObjectFile::Reader::Stab>* stabs)
 }
 
 
+static void dumpAtomLikeNM(ObjectFile::Atom* atom)
+{
+       uint32_t size = atom->getSize();
+       
+       const char* visibility;
+       switch ( atom->getScope() ) {
+               case ObjectFile::Atom::scopeTranslationUnit:
+                       visibility = "internal";
+                       break;
+               case ObjectFile::Atom::scopeLinkageUnit:
+                       visibility = "hidden  ";
+                       break;
+               case ObjectFile::Atom::scopeGlobal:
+                       visibility = "global  ";
+                       break;
+               default:
+                       visibility = "        ";
+                       break;
+       }
+
+       const char* kind;
+       switch ( atom->getDefinitionKind() ) {
+               case ObjectFile::Atom::kRegularDefinition:
+                       kind = "regular  ";
+                       break;
+               case ObjectFile::Atom::kTentativeDefinition:
+                       kind = "tentative";
+                       break;
+               case ObjectFile::Atom::kWeakDefinition:
+                       kind = "weak     ";
+                       break;
+               case ObjectFile::Atom::kAbsoluteSymbol:
+                       kind = "absolute ";
+                       break;
+               default:
+                       kind = "         ";
+                       break;
+       }
+
+       printf("0x%08X %s %s %s\n", size, visibility, kind, atom->getDisplayName());
+}
+
+
 static void dumpAtom(ObjectFile::Atom* atom)
 {
        if(sMatchName && strcmp(sMatchName, atom->getDisplayName()))
@@ -207,7 +259,7 @@ static void dumpAtom(ObjectFile::Atom* atom)
                }
 
        // segment and section
-       if(!sPrintRestrict)
+       if(!sPrintRestrict && (atom->getSectionName() != NULL) )
                printf("section: %s,%s\n", atom->getSegment().getName(), atom->getSectionName());
 
        // attributes
@@ -217,6 +269,8 @@ static void dumpAtom(ObjectFile::Atom* atom)
                        printf("dont-dead-strip ");
                if ( atom->isZeroFill() )
                        printf("zero-fill ");
+               if ( atom->isThumb() )
+                       printf("thumb ");
                printf("\n");
        }
        
@@ -307,8 +361,12 @@ static void dumpFile(ObjectFile::Reader* reader)
        if ( sSort )
                std::sort(sortedAtoms.begin(), sortedAtoms.end(), AtomSorter());
        
-       for(std::vector<ObjectFile::Atom*>::iterator it=sortedAtoms.begin(); it != sortedAtoms.end(); ++it)
-               dumpAtom(*it);
+       for(std::vector<ObjectFile::Atom*>::iterator it=sortedAtoms.begin(); it != sortedAtoms.end(); ++it) {
+               if ( sNMmode )
+                       dumpAtomLikeNM(*it);
+               else
+                       dumpAtom(*it);
+       }
 }
 
 
@@ -341,6 +399,12 @@ static ObjectFile::Reader* createReader(const char* path, const ObjectFile::Read
                return new mach_o::relocatable::Reader<ppc64>::Reader(p, path, 0, options, 0);
        else if ( mach_o::relocatable::Reader<x86_64>::validFile(p) )
                return new mach_o::relocatable::Reader<x86_64>::Reader(p, path, 0, options, 0);
+       else if ( mach_o::relocatable::Reader<arm>::validFile(p) )
+               return new mach_o::relocatable::Reader<arm>::Reader(p, path, 0, options, 0);
+       if ( lto::Reader::validFile(p, stat_buf.st_size, 0) ) {
+               return new lto::Reader(p, stat_buf.st_size, path, 0, options, 0);
+       }
+       
        throwf("not a mach-o object file: %s", path);
 }
 
@@ -373,6 +437,9 @@ int main(int argc, const char* argv[])
                                if ( strcmp(arg, "-no_content") == 0 ) {
                                        sDumpContent = false;
                                }
+                               else if ( strcmp(arg, "-nm") == 0 ) {
+                                       sNMmode = true;
+                               }
                                else if ( strcmp(arg, "-stabs") == 0 ) {
                                        sDumpStabs = true;
                                }
old mode 100644 (file)
new mode 100755 (executable)
index 3f570c8..37a2892
@@ -45,6 +45,7 @@
 //
 
 
+
 namespace ObjectFile {
 
 
@@ -59,14 +60,15 @@ struct LineInfo
 class ReaderOptions
 {
 public:
-                                               ReaderOptions() : fFullyLoadArchives(false), fLoadAllObjcObjectsFromArchives(false), fFlatNamespace(false), fLinkingMainExecutable(false), 
+                                               ReaderOptions() : fFullyLoadArchives(false), fLoadAllObjcObjectsFromArchives(false), fFlatNamespace(false),
+                                                                               fLinkingMainExecutable(false), fSlowx86Stubs(false),
                                                                                fForFinalLinkedImage(false), fForStatic(false), fForDyld(false), fMakeTentativeDefinitionsReal(false), 
                                                                                fWhyLoad(false), fRootSafe(false), fSetuidSafe(false),fDebugInfoStripping(kDebugInfoFull),
-                                                                               fLogObjectFiles(false), fLogAllFiles(false),
+                                                                               fImplicitlyLinkPublicDylibs(true), fLogObjectFiles(false), fLogAllFiles(false),
                                                                                fTraceDylibs(false), fTraceIndirectDylibs(false), fTraceArchives(false), 
                                                                                fTraceOutputFile(NULL), fVersionMin(kMinUnset) {}
        enum DebugInfoStripping { kDebugInfoNone, kDebugInfoMinimal, kDebugInfoFull };
-       enum VersionMin { kMinUnset, k10_1, k10_2, k10_3, k10_4, k10_5 };
+       enum VersionMin { kMinUnset, k10_1, k10_2, k10_3, k10_4, k10_5, k10_6 };
 
        struct AliasPair {
                const char*                     realName;
@@ -77,6 +79,7 @@ public:
        bool                                    fLoadAllObjcObjectsFromArchives;
        bool                                    fFlatNamespace;
        bool                                    fLinkingMainExecutable;
+       bool                                    fSlowx86Stubs;
        bool                                    fForFinalLinkedImage;
        bool                                    fForStatic;
        bool                                    fForDyld;
@@ -85,6 +88,7 @@ public:
        bool                                    fRootSafe;
        bool                                    fSetuidSafe;
        DebugInfoStripping              fDebugInfoStripping;
+       bool                                    fImplicitlyLinkPublicDylibs;
        bool                                    fLogObjectFiles;
        bool                                    fLogAllFiles;
        bool                                    fTraceDylibs;
@@ -110,7 +114,7 @@ public:
                const char* string;
        };
        enum ObjcConstraint { kObjcNone,  kObjcRetainRelease,  kObjcRetainReleaseOrGC,  kObjcGC };
-       enum CpuConstraint  { kCpuAny,  kCpuG3,  kCpuG4,  kCpuG5  };
+       enum CpuConstraint  { kCpuAny = 0 };
 
        class DylibHander
        {
@@ -129,12 +133,17 @@ public:
        virtual std::vector<class Atom*>*       getJustInTimeAtomsFor(const char* name) = 0;
        virtual std::vector<Stab>*                      getStabs() = 0;
        virtual ObjcConstraint                          getObjCConstraint()                     { return kObjcNone; }
-       virtual CpuConstraint                           getCpuConstraint()                      { return kCpuAny; }
+       virtual uint32_t                                        updateCpuConstraint(uint32_t current) { return current; }
        virtual bool                                            objcReplacementClasses()        { return false; }
 
        // For relocatable object files only
        virtual bool                                            canScatterAtoms()                       { return true; }
-       virtual void                                            optimize(std::vector<ObjectFile::Atom*>&, std::vector<ObjectFile::Atom*>&, uint32_t)            { }
+       virtual void                                            optimize(std::vector<ObjectFile::Atom*>&, std::vector<ObjectFile::Atom*>&, 
+                                                                                                       std::vector<const char*>&,  uint32_t, ObjectFile::Reader* writer, 
+                                                                                                       bool allGlobalsAReDeadStripRoots, int okind, 
+                                                                                                       bool verbose, bool saveTemps, const char* outputFilePath,
+                                                                                                       bool pie, bool allowTextRelocs) { }
+       virtual bool                                            hasLongBranchStubs()            { return false; }
 
        // For Dynamic Libraries only
        virtual const char*                                     getInstallPath()                        { return NULL; }
@@ -148,7 +157,8 @@ public:
        virtual bool                                            providedExportAtom()            { return false; }
        virtual const char*                                     parentUmbrella()                        { return NULL; }
        virtual std::vector<const char*>*       getAllowableClients()           { return NULL; }
-
+       virtual bool                                            hasWeakExternals()                      { return false; }
+       virtual bool                                            isLazyLoadedDylib()                     { return false; }
 
 protected:
                                                                                Reader() {}
@@ -252,6 +262,7 @@ public:
        virtual SymbolTableInclusion                    getSymbolTableInclusion() const = 0;
        virtual bool                                                    dontDeadStrip() const = 0;
        virtual bool                                                    isZeroFill() const = 0;
+       virtual bool                                                    isThumb() const = 0;
        virtual uint64_t                                                getSize() const = 0;
        virtual std::vector<ObjectFile::Reference*>&  getReferences() const = 0;
        virtual bool                                                    mustRemainInSection() const = 0;
old mode 100644 (file)
new mode 100755 (executable)
index ccb3f2f..cddd45c
@@ -113,6 +113,7 @@ public:
        virtual SymbolTableInclusion                            getSymbolTableInclusion() const { return ObjectFile::Atom::kSymbolTableNotIn; }
        virtual bool                                                            dontDeadStrip() const           { return true; }
        virtual bool                                                            isZeroFill() const                      { return false; }
+       virtual bool                                                            isThumb() const                         { return false; }
        virtual uint64_t                                                        getSize() const                         { return fFileLength; }
        virtual std::vector<ObjectFile::Reference*>&  getReferences() const             { return (std::vector<ObjectFile::Reference*>&)(fReferences); }
        virtual bool                                                            mustRemainInSection() const { return false; }
old mode 100644 (file)
new mode 100755 (executable)
index 50bd636..e85cf2a
@@ -1,6 +1,6 @@
 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
  *
- * Copyright (c) 2005-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2005-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <mach/vm_prot.h>
-#include <math.h>
 #include <fcntl.h>
 #include <vector>
 
+#include "configure.h"
 #include "Options.h"
+#include "Architectures.hpp"
+#include "MachOFileAbstraction.hpp"
+
+extern void printLTOVersion(Options &opts);
+
+
+static bool                    sEmitWarnings = true;
+static const char*     sWarningsSideFilePath = NULL;
+static FILE*           sWarningsSideFile = NULL;
+
+void warning(const char* format, ...)
+{
+       if ( sEmitWarnings ) {
+               va_list list;
+               if ( sWarningsSideFilePath != NULL ) {
+                       if ( sWarningsSideFile == NULL )
+                               sWarningsSideFile = fopen(sWarningsSideFilePath, "a");
+               }
+               va_start(list, format);
+               fprintf(stderr, "ld warning: ");
+               vfprintf(stderr, format, list);
+               fprintf(stderr, "\n");
+               if ( sWarningsSideFile != NULL ) {
+                       fprintf(sWarningsSideFile, "ld warning: ");
+                       vfprintf(sWarningsSideFile, format, list);
+                       fprintf(sWarningsSideFile, "\n");
+                       fflush(sWarningsSideFile);
+               }
+               va_end(list);
+       }
+}
 
 void throwf(const char* format, ...)
 {
@@ -45,10 +76,10 @@ void throwf(const char* format, ...)
 }
 
 Options::Options(int argc, const char* argv[])
-       : fOutputFile("a.out"), fArchitecture(0), fOutputKind(kDynamicExecutable), fPrebind(false), fBindAtLoad(false),
-         fKeepPrivateExterns(false),
-         fInterposable(false), fNeedsModuleTable(false), fIgnoreOtherArchFiles(false), fForceSubtypeAll(false), 
-         fDeadStrip(kDeadStripOff), fNameSpace(kTwoLevelNameSpace),
+       : fOutputFile("a.out"), fArchitecture(0), fSubArchitecture(0), fOutputKind(kDynamicExecutable), 
+         fHasPreferredSubType(false), fPrebind(false), fBindAtLoad(false), fKeepPrivateExterns(false),
+         fNeedsModuleTable(false), fIgnoreOtherArchFiles(false), fForceSubtypeAll(false), 
+         fInterposeMode(kInterposeNone), fDeadStrip(kDeadStripOff), fNameSpace(kTwoLevelNameSpace),
          fDylibCompatVersion(0), fDylibCurrentVersion(0), fDylibInstallName(NULL), fFinalName(NULL), fEntryName("start"), fBaseAddress(0),
          fBaseWritableAddress(0), fSplitSegs(false),
          fExportMode(kExportDefault), fLibrarySearchMode(kSearchAllDirsForDylibsThenAllDirsForArchives),
@@ -63,7 +94,8 @@ Options::Options(int argc, const char* argv[])
          fTraceDylibSearching(false), fPause(false), fStatistics(false), fPrintOptions(false),
          fSharedRegionEligible(false), fPrintOrderFileStatistics(false),  
          fReadOnlyx86Stubs(false), fPositionIndependentExecutable(false), fMaxMinimumHeaderPad(false),
-         fDeadStripDylibs(false), fSuppressWarnings(false), fSaveTempFiles(false)
+         fDeadStripDylibs(false),  fAllowTextRelocs(false), fWarnTextRelocs(false), 
+         fUsingLazyDylibLinking(false), fEncryptable(true), fSaveTempFiles(false)
 {
        this->checkForClassic(argc, argv);
        this->parsePreCommandLineEnvironmentSettings();
@@ -82,10 +114,6 @@ const ObjectFile::ReaderOptions& Options::readerOptions()
        return fReaderOptions;
 }
 
-cpu_type_t Options::architecture()
-{
-       return fArchitecture;
-}
 
 const char*    Options::getOutputFilePath()
 {
@@ -157,9 +185,17 @@ bool Options::keepPrivateExterns()
        return fKeepPrivateExterns;
 }
 
-bool Options::interposable()
+bool Options::interposable(const char* name)
 {
-       return fInterposable;
+       switch ( fInterposeMode ) {
+               case kInterposeNone:
+                       return false;
+               case kInterposeAllExternal:
+                       return true;
+               case kInterposeSome:
+                       return fInterposeList.contains(name);
+       }
+       throw "internal error";
 }
 
 bool Options::needsModuleTable()
@@ -268,6 +304,19 @@ bool Options::hasExportRestrictList()
        return (fExportMode != kExportDefault);
 }
 
+bool Options::hasExportMaskList()
+{
+       return (fExportMode == kExportSome);
+}
+
+
+bool Options::hasWildCardExportRestrictList()
+{
+       // has -exported_symbols_list which contains some wildcards
+       return ((fExportMode == kExportSome) && fExportSymbols.hasWildCards());
+}
+
+
 bool Options::allGlobalsAreDeadStripRoots()
 {
        // -exported_symbols_list means globals are not exported by default
@@ -365,22 +414,74 @@ void Options::parseArch(const char* architecture)
 {
        if ( architecture == NULL )
                throw "-arch must be followed by an architecture string";
-       if ( strcmp(architecture, "ppc") == 0 )
+       if ( strcmp(architecture, "ppc") == 0 ) {
                fArchitecture = CPU_TYPE_POWERPC;
-       else if ( strcmp(architecture, "ppc64") == 0 )
+               fSubArchitecture = CPU_SUBTYPE_POWERPC_ALL;
+       }
+       else if ( strcmp(architecture, "ppc64") == 0 ) {
                fArchitecture = CPU_TYPE_POWERPC64;
-       else if ( strcmp(architecture, "i386") == 0 )
+               fSubArchitecture = CPU_SUBTYPE_POWERPC_ALL;
+       }
+       else if ( strcmp(architecture, "i386") == 0 ) {
                fArchitecture = CPU_TYPE_I386;
-       else if ( strcmp(architecture, "x86_64") == 0 )
+               fSubArchitecture = CPU_SUBTYPE_I386_ALL;
+       }
+       else if ( strcmp(architecture, "x86_64") == 0 ) {
                fArchitecture = CPU_TYPE_X86_64;
+               fSubArchitecture = CPU_SUBTYPE_X86_64_ALL;
+       }
+       else if ( strcmp(architecture, "arm") == 0 ) {
+               fArchitecture = CPU_TYPE_ARM;
+               fSubArchitecture = CPU_SUBTYPE_ARM_ALL;
+       }
        // compatibility support for cpu-sub-types
-       else if ( (strcmp(architecture, "ppc750") == 0)
-                       || (strcmp(architecture, "ppc7400") == 0)
-                       || (strcmp(architecture, "ppc7450") == 0)
-                       || (strcmp(architecture, "ppc970") == 0) )
+       else if ( strcmp(architecture, "ppc750") == 0 ) {
+               fArchitecture = CPU_TYPE_POWERPC;
+               fSubArchitecture = CPU_SUBTYPE_POWERPC_750;
+               fHasPreferredSubType = true;
+       }
+       else if ( strcmp(architecture, "ppc7400") == 0 ) {
+               fArchitecture = CPU_TYPE_POWERPC;
+               fSubArchitecture = CPU_SUBTYPE_POWERPC_7400;
+               fHasPreferredSubType = true;
+       }
+       else if ( strcmp(architecture, "ppc7450") == 0 ) {
                fArchitecture = CPU_TYPE_POWERPC;
+               fSubArchitecture = CPU_SUBTYPE_POWERPC_7450;
+               fHasPreferredSubType = true;
+       }
+       else if ( strcmp(architecture, "ppc970") == 0 ) {
+               fArchitecture = CPU_TYPE_POWERPC;
+               fSubArchitecture = CPU_SUBTYPE_POWERPC_970;
+               fHasPreferredSubType = true;
+       }
+       else if ( strcmp(architecture, "armv6") == 0 ) {
+               fArchitecture = CPU_TYPE_ARM;
+               fSubArchitecture = CPU_SUBTYPE_ARM_V6;
+               fHasPreferredSubType = true;
+       }
+       else if ( strcmp(architecture, "armv5") == 0 ) {
+               fArchitecture = CPU_TYPE_ARM;
+               fSubArchitecture = CPU_SUBTYPE_ARM_V5TEJ;
+               fHasPreferredSubType = true;
+       }
+       else if ( strcmp(architecture, "armv4t") == 0 ) {
+               fArchitecture = CPU_TYPE_ARM;
+               fSubArchitecture = CPU_SUBTYPE_ARM_V4T;
+               fHasPreferredSubType = true;
+       }
+       else if ( strcmp(architecture, "xscale") == 0 ) {
+               fArchitecture = CPU_TYPE_ARM;
+               fSubArchitecture = CPU_SUBTYPE_ARM_XSCALE;
+               fHasPreferredSubType = true;
+       }
+       else if ( strcmp(architecture, "armv7") == 0 ) {
+               fArchitecture = CPU_TYPE_ARM;
+               fSubArchitecture = CPU_SUBTYPE_ARM_V7;
+               fHasPreferredSubType = true;
+       }
        else
-               throwf(" unknown/unsupported architecture name for: -arch %s", architecture);
+               throwf("unknown/unsupported architecture name for: -arch %s", architecture);
 }
 
 bool Options::checkForFile(const char* format, const char* dir, const char* rootName, FileInfo& result)
@@ -401,7 +502,7 @@ bool Options::checkForFile(const char* format, const char* dir, const char* root
 }
 
 
-Options::FileInfo Options::findLibrary(const char* rootName)
+Options::FileInfo Options::findLibrary(const char* rootName, bool dylibsOnly)
 {
        FileInfo result;
        const int rootNameLen = strlen(rootName);
@@ -437,12 +538,14 @@ Options::FileInfo Options::findLibrary(const char* rootName)
                                        }
                                }
                                // next look in all directories for just for archives
-                               for (std::vector<const char*>::iterator it = fLibrarySearchPaths.begin();
-                                        it != fLibrarySearchPaths.end();
-                                        it++) {
-                                       const char* dir = *it;
-                                       if ( checkForFile("%s/lib%s.a", dir, rootName, result) )
-                                               return result;
+                               if ( !dylibsOnly ) {
+                                       for (std::vector<const char*>::iterator it = fLibrarySearchPaths.begin();
+                                                it != fLibrarySearchPaths.end();
+                                                it++) {
+                                               const char* dir = *it;
+                                               if ( checkForFile("%s/lib%s.a", dir, rootName, result) )
+                                                       return result;
+                                       }
                                }
                                break;
 
@@ -456,7 +559,7 @@ Options::FileInfo Options::findLibrary(const char* rootName)
                                                return result;
                                        if ( lookForDylibs && checkForFile("%s/lib%s.so", dir, rootName, result) )
                                                return result;
-                                       if ( checkForFile("%s/lib%s.a", dir, rootName, result) )
+                                       if ( !dylibsOnly && checkForFile("%s/lib%s.a", dir, rootName, result) )
                                                return result;
                                }
                                break;
@@ -619,13 +722,21 @@ Options::FileInfo Options::findFileUsingPaths(const char* path)
                }
        } 
        else {
-               for (std::vector<const char*>::iterator it = fLibrarySearchPaths.begin();
-                        it != fLibrarySearchPaths.end();
-                        it++) {
-                       const char* dir = *it;
-                       //fprintf(stderr,"Finding Library: %s/%s\n", dir, leafName);
-                       if ( checkForFile("%s/%s", dir, leafName, result) )
-                               return result;
+               // if this is a .dylib inside a framework, do not search -L paths
+               // <rdar://problem/5427952> ld64's re-export cycle detection logic prevents use of X11 libGL on Leopard 
+               int leafLen = strlen(leafName);
+               bool embeddedDylib = ( (leafLen > 6) 
+                                       && (strcmp(&leafName[leafLen-6], ".dylib") == 0) 
+                                       && (strstr(path, ".framework/") != NULL) );
+               if ( !embeddedDylib ) {
+                       for (std::vector<const char*>::iterator it = fLibrarySearchPaths.begin();
+                                it != fLibrarySearchPaths.end();
+                                it++) {
+                               const char* dir = *it;
+                               //fprintf(stderr,"Finding Library: %s/%s\n", dir, leafName);
+                               if ( checkForFile("%s/%s", dir, leafName, result) )
+                                       return result;
+                       }
                }
        }
 
@@ -638,7 +749,7 @@ void Options::parseSegAddrTable(const char* segAddrPath, const char* installPath
 {
        FILE* file = fopen(segAddrPath, "r");
        if ( file == NULL ) {
-               fprintf(stderr, "ld64: warning, -seg_addr_table file cannot be read: %s\n", segAddrPath);
+               warning("-seg_addr_table file cannot be read: %s", segAddrPath);
                return;
        }
        
@@ -870,7 +981,7 @@ void Options::loadExportFile(const char* fileOfExports, const char* option, SetW
                }
        }
        if ( state == inSymbol ) {
-               fprintf(stderr, "ld64 warning: missing line-end at end of file \"%s\"\n", fileOfExports);
+               warning("missing line-end at end of file \"%s\"", fileOfExports);
                int len = end-symbolStart+1;
                char* temp = new char[len];
                strlcpy(temp, symbolStart, len);
@@ -922,7 +1033,7 @@ void Options::parseAliasFile(const char* fileOfAliases)
                        break;
                case inRealName:
                        if ( *s == '\n' ) {
-                               fprintf(stderr, "ld64 warning: line needs two symbols but has only one at line #%d in \"%s\"\n", lineNumber, fileOfAliases);
+                               warning("line needs two symbols but has only one at line #%d in \"%s\"", lineNumber, fileOfAliases);
                                ++lineNumber;
                                state = lineStart;
                        }
@@ -933,7 +1044,7 @@ void Options::parseAliasFile(const char* fileOfAliases)
                        break;
                case inBetween:
                        if ( *s == '\n' ) {
-                               fprintf(stderr, "ld64 warning: line needs two symbols but has only one at line #%d in \"%s\"\n", lineNumber, fileOfAliases);
+                               warning("line needs two symbols but has only one at line #%d in \"%s\"", lineNumber, fileOfAliases);
                                ++lineNumber;
                                state = lineStart;
                        }
@@ -1010,7 +1121,7 @@ Options::Treatment Options::parseTreatment(const char* treatment)
                return kInvalid;
 }
 
-void Options::setVersionMin(const char* version)
+void Options::setMacOSXVersionMin(const char* version)
 {
        if ( version == NULL )
                throw "-macosx_version_min argument missing";
@@ -1031,13 +1142,39 @@ void Options::setVersionMin(const char* version)
                        case 4:
                                fReaderOptions.fVersionMin = ObjectFile::ReaderOptions::k10_4;
                                break;
-                       default:
+                       case 5:
                                fReaderOptions.fVersionMin = ObjectFile::ReaderOptions::k10_5;
                                break;
+                       case 6:
+                               fReaderOptions.fVersionMin = ObjectFile::ReaderOptions::k10_6;
+                               break;
+                       default:
+                               fReaderOptions.fVersionMin = ObjectFile::ReaderOptions::k10_6;
+                               break;
                        }
        }
        else {
-               fprintf(stderr, "ld64: unknown option to -macosx_version_min not 10.x");
+               warning("unknown option to -macosx_version_min, not 10.x");
+       }
+}
+
+void Options::setIPhoneVersionMin(const char* version)
+{
+       if ( version == NULL )
+               throw "-iphoneos_version_min argument missing";
+
+       if ( ((strncmp(version, "1.", 2) == 0) || (strncmp(version, "2.", 2) == 0)) && isdigit(version[2]) ) {
+               int num = version[2] - '0';
+               switch ( num ) {
+                       case 2:
+                               // TODO: store deployment version
+                               break;
+                       default:
+                               break;
+               }
+       }
+       else {
+               warning("unknown option to -iphoneos_version_min, not 1.x or 2.x");
        }
 }
 
@@ -1288,6 +1425,12 @@ void Options::parseOrderFile(const char* path, bool cstring)
                                        else
                                                symbolStart = NULL;
                                }
+                               else if ( strncmp(symbolStart, "arm:", 4) == 0 ) {
+                                       if ( fArchitecture == CPU_TYPE_ARM )
+                                               symbolStart = &symbolStart[4];
+                                       else
+                                               symbolStart = NULL;
+                               }
                                if ( symbolStart != NULL ) {
                                        char* objFileName = NULL;
                                        char* colon = strstr(symbolStart, ".o:");
@@ -1329,7 +1472,7 @@ void Options::parseSectionOrderFile(const char* segment, const char* section, co
                parseOrderFile(path, true);
        }
        else if ( (strncmp(section, "__literal",9) == 0) && (strcmp(segment, "__TEXT") == 0) ) {
-               fprintf(stderr, "ld64 warning: sorting of __literal[4,8,16] sections not supported\n");
+               warning("sorting of __literal[4,8,16] sections not supported");
        }
        else {
                // ignore section information and append all symbol names to global order file
@@ -1344,7 +1487,7 @@ void Options::addSection(const char* segment, const char* section, const char* p
        if ( strlen(section) > 16 ) {
                char* tmp = strdup(section);
                tmp[16] = '\0';
-               fprintf(stderr, "ld64 warning: -seccreate section name (%s) truncated to 16 chars (%s)\n", section, tmp);
+               warning("-seccreate section name (%s) truncated to 16 chars (%s)\n", section, tmp);
                section = tmp;
        }
 
@@ -1381,14 +1524,14 @@ void Options::addSectionAlignment(const char* segment, const char* section, cons
        if ( value > 0x8000 )
                throw "argument for -sectalign must be less than or equal to 0x8000";
        if ( value == 0 ) {
-               fprintf(stderr, "ld64 warning: zero is not a valid -sectalign\n");
+               warning("zero is not a valid -sectalign");
                value = 1;
        }
 
        // alignment is power of 2 (e.g. page alignment = 12)
        uint8_t alignment = (uint8_t)__builtin_ctz(value);
        if ( (unsigned long)(1 << alignment) != value ) {
-               fprintf(stderr, "ld64 warning: alignment for -sectalign %s %s is not a power of two, using 0x%X\n",
+               warning("alignment for -sectalign %s %s is not a power of two, using 0x%X",
                        segment, section, 1 << alignment);
        }
 
@@ -1413,8 +1556,7 @@ void Options::addLibrary(const FileInfo& info)
 
 void Options::warnObsolete(const char* arg)
 {
-       if ( emitWarnings() )
-               fprintf(stderr, "ld64: warning: option %s is obsolete and being ignored\n", arg);
+       warning("option %s is obsolete and being ignored", arg);
 }
 
 
@@ -1489,7 +1631,7 @@ void Options::parse(int argc, const char* argv[])
                        else if ( strcmp(arg, "-o") == 0 ) {
                                fOutputFile = argv[++i];
                        }
-                       else if ( arg[1] == 'l' ) {
+                       else if ( (arg[1] == 'l') && (strncmp(arg,"-lazy_",6) !=0) ) {
                                addLibrary(findLibrary(&arg[2]));
                        }
                        // This causes a dylib to be weakly bound at
@@ -1499,6 +1641,12 @@ void Options::parse(int argc, const char* argv[])
                                info.options.fWeakImport = true;
                                addLibrary(info);
                        }
+                       else if ( strncmp(arg, "-lazy-l", 7) == 0 ) {
+                               FileInfo info = findLibrary(&arg[7], true);
+                               info.options.fLazyLoad = true;
+                               addLibrary(info);
+                               fUsingLazyDylibLinking = true;
+                       }
                        // Avoid lazy binding.
                        // ??? Deprecate.
                        else if ( strcmp(arg, "-bind_at_load") == 0 ) {
@@ -1576,6 +1724,11 @@ void Options::parse(int argc, const char* argv[])
                                 if ( address == NULL )
                                        throwf("%s missing <address>", arg);
                                fBaseAddress = parseAddress(address);
+                               uint64_t temp = (fBaseAddress+4095) & (-4096); // page align
+                               if ( fBaseAddress != temp ) {
+                                       warning("-seg1addr not page aligned, rounding up");
+                                       fBaseAddress = temp;
+                               }
                        }
                        else if ( strcmp(arg, "-e") == 0 ) {
                                fEntryName = argv[++i];
@@ -1596,11 +1749,23 @@ void Options::parse(int argc, const char* argv[])
                        // Ensure that all calls to exported symbols go through lazy pointers.  Multi-module
                        // just ensures that this happens for cross object file boundaries.
                        else if ( (strcmp(arg, "-interposable") == 0) || (strcmp(arg, "-multi_module") == 0)) {
-                                fInterposable = true;
+                               switch ( fInterposeMode ) {
+                                       case kInterposeNone:
+                                       case kInterposeAllExternal:
+                                               fInterposeMode = kInterposeAllExternal;
+                                               break;
+                                       case kInterposeSome:
+                                               // do nothing, -interposable_list overrides -interposable"
+                                               break;
+                               }
+                       }
+                       else if ( strcmp(arg, "-interposable_list") == 0 ) {
+                               fInterposeMode = kInterposeSome;
+                               loadExportFile(argv[++i], "-interposable_list", fInterposeList);
                        }
                        // Default for -interposable/-multi_module/-single_module.
                        else if ( strcmp(arg, "-single_module") == 0 ) {
-                                fInterposable = false;
+                               fInterposeMode = kInterposeNone;
                        }
                        else if ( strcmp(arg, "-exported_symbols_list") == 0 ) {
                                if ( fExportMode == kDontExportSome )
@@ -1651,6 +1816,12 @@ void Options::parse(int argc, const char* argv[])
                                info.options.fWeakImport = true;
                                addLibrary(info);
                        }
+                       else if ( strcmp(arg, "-lazy_library") == 0 ) {
+                               FileInfo info = findFile(argv[++i]);
+                               info.options.fLazyLoad = true;
+                               addLibrary(info);
+                               fUsingLazyDylibLinking = true;
+                       }
                        else if ( strcmp(arg, "-framework") == 0 ) {
                                addLibrary(findFramework(argv[++i]));
                        }
@@ -1659,6 +1830,12 @@ void Options::parse(int argc, const char* argv[])
                                info.options.fWeakImport = true;
                                addLibrary(info);
                        }
+                       else if ( strcmp(arg, "-lazy_framework") == 0 ) {
+                               FileInfo info = findFramework(argv[++i]);
+                               info.options.fLazyLoad = true;
+                               addLibrary(info);
+                               fUsingLazyDylibLinking = true;
+                       }
                        else if ( strcmp(arg, "-search_paths_first") == 0 ) {
                                // previously handled by buildSearchPaths()
                        }
@@ -1674,12 +1851,23 @@ void Options::parse(int argc, const char* argv[])
                        // or suppressed.  Currently we do nothing with the
                        // flag.
                        else if ( strcmp(arg, "-read_only_relocs") == 0 ) {
-                               Treatment temp = parseTreatment(argv[++i]);
-
-                               if ( temp == kNULL )
-                                       throw "-read_only_relocs missing [ warning | error | suppress ]";
-                               else if ( temp == kInvalid )
-                                       throw "invalid option to -read_only_relocs [ warning | error | suppress ]";
+                               switch ( parseTreatment(argv[++i]) ) {
+                                       case kNULL:
+                                       case kInvalid:
+                                               throw "-read_only_relocs missing [ warning | error | suppress ]";
+                                       case kWarning:
+                                               fWarnTextRelocs = true;
+                                               fAllowTextRelocs = true;
+                                               break;
+                                       case kSuppress:
+                                               fWarnTextRelocs = false;
+                                               fAllowTextRelocs = true;
+                                               break;
+                                       case kError:
+                                               fWarnTextRelocs = false;
+                                               fAllowTextRelocs = false;
+                                               break;
+                               }
                        }
                        else if ( strcmp(arg, "-sect_diff_relocs") == 0 ) {
                                warnObsolete(arg);
@@ -1749,8 +1937,8 @@ void Options::parse(int argc, const char* argv[])
                                        throw "-segaddr missing segName Adddress";
                                seg.address = parseAddress(argv[++i]);
                                uint64_t temp = seg.address & (-4096); // page align
-                               if ( (seg.address != temp) && emitWarnings() )
-                                       fprintf(stderr, "ld64: warning, -segaddr %s not page aligned, rounding down\n", seg.name);
+                               if ( (seg.address != temp)  )
+                                       warning("-segaddr %s not page aligned, rounding down", seg.name);
                                fCustomSegmentAddresses.push_back(seg);
                        }
                        // ??? Deprecate when we deprecate split-seg.
@@ -1788,8 +1976,8 @@ void Options::parse(int argc, const char* argv[])
                                        throw "-pagezero_size missing <size>";
                                fZeroPageSize = parseAddress(size);
                                uint64_t temp = fZeroPageSize & (-4096); // page align
-                               if ( (fZeroPageSize != temp) && emitWarnings() )
-                                       fprintf(stderr, "ld64: warning, -pagezero_size not page aligned, rounding down\n");
+                               if ( (fZeroPageSize != temp)  )
+                                       warning("-pagezero_size not page aligned, rounding down");
                                 fZeroPageSize = temp;
                        }
                        else if ( strcmp(arg, "-stack_addr") == 0 ) {
@@ -1804,8 +1992,8 @@ void Options::parse(int argc, const char* argv[])
                                        throw "-stack_size missing <address>";
                                fStackSize = parseAddress(size);
                                uint64_t temp = fStackSize & (-4096); // page align
-                               if ( (fStackSize != temp) && emitWarnings() )
-                                       fprintf(stderr, "ld64: warning, -stack_size not page aligned, rounding down\n");
+                               if ( (fStackSize != temp)  )
+                                       warning("-stack_size not page aligned, rounding down");
                        }
                        else if ( strcmp(arg, "-allow_stack_execute") == 0 ) {
                                fExecutableStack = true;
@@ -1839,7 +2027,10 @@ void Options::parse(int argc, const char* argv[])
                        }
                        // Use this flag to set default behavior for deployement targets.
                        else if ( strcmp(arg, "-macosx_version_min") == 0 ) {
-                               setVersionMin(argv[++i]);
+                               setMacOSXVersionMin(argv[++i]);
+                       }
+                       else if ( (strcmp(arg, "-aspen_version_min") == 0) || (strcmp(arg, "-iphone_version_min") == 0) || (strcmp(arg, "-iphoneos_version_min") == 0) ) {
+                               setIPhoneVersionMin(argv[++i]);
                        }
                        else if ( strcmp(arg, "-multiply_defined") == 0 ) {
                                //warnObsolete(arg);
@@ -2082,6 +2273,9 @@ void Options::parse(int argc, const char* argv[])
                        else if ( strcmp(arg, "-read_only_stubs") == 0 ) {
                                fReadOnlyx86Stubs = true;
                        }
+                       else if ( strcmp(arg, "-slow_stubs") == 0 ) {
+                               fReaderOptions.fSlowx86Stubs = true;
+                       }
                        else if ( strcmp(arg, "-map") == 0 ) {
                                fMapPath = argv[++i];
                                if ( fMapPath == NULL )
@@ -2091,7 +2285,7 @@ void Options::parse(int argc, const char* argv[])
                                fPositionIndependentExecutable = true;
                        }
                        else if ( strncmp(arg, "-reexport-l", 11) == 0 ) {
-                               FileInfo info = findLibrary(&arg[11]);
+                               FileInfo info = findLibrary(&arg[11], true);
                                info.options.fReExport = true;
                                addLibrary(info);
                        }
@@ -2108,9 +2302,15 @@ void Options::parse(int argc, const char* argv[])
                        else if ( strcmp(arg, "-dead_strip_dylibs") == 0 ) {
                                fDeadStripDylibs = true;
                        }
+                       else if ( strcmp(arg, "-no_implicit_dylibs") == 0 ) {
+                               fReaderOptions.fImplicitlyLinkPublicDylibs = false;
+                       }
                        else if ( strcmp(arg, "-new_linker") == 0 ) {
                                // ignore
                        }
+                       else if ( strcmp(arg, "-no_encryption") == 0 ) {
+                               fEncryptable = false;
+                       }
                        else {
                                throwf("unknown option: %s", arg);
                        }
@@ -2123,6 +2323,11 @@ void Options::parse(int argc, const char* argv[])
                                fInputFiles.push_back(info);
                }
        }
+       
+       // if a -lazy option was used, implicitly link in lazydylib1.o
+       if ( fUsingLazyDylibLinking ) {
+               addLibrary(findLibrary("lazydylib1.o"));
+       }
 }
 
 
@@ -2156,8 +2361,12 @@ void Options::buildSearchPaths(int argc, const char* argv[])
                        extern const char ldVersionString[];
                        fprintf(stderr, "%s", ldVersionString);
                         // if only -v specified, exit cleanly
-                        if ( argc == 2 )
+                        if ( argc == 2 ) {
+#if LTO_SUPPORT
+                               printLTOVersion(*this);
+#endif
                                exit(0);
+                       }
                }
                else if ( strcmp(argv[i], "-syslibroot") == 0 ) {
                        const char* path = argv[++i];
@@ -2170,7 +2379,7 @@ void Options::buildSearchPaths(int argc, const char* argv[])
                        fLibrarySearchMode = kSearchDylibAndArchiveInEachDir;
                }
                else if ( strcmp(argv[i], "-w") == 0 ) {
-                       fSuppressWarnings = true;
+                       sEmitWarnings = false;
                }
        }
        if ( addStandardLibraryDirectories ) {
@@ -2179,7 +2388,8 @@ void Options::buildSearchPaths(int argc, const char* argv[])
 
                frameworkPaths.push_back("/Library/Frameworks/");
                frameworkPaths.push_back("/System/Library/Frameworks/");
-               frameworkPaths.push_back("/Network/Library/Frameworks/");
+               // <rdar://problem/5433882> remove /Network from default search path
+               //frameworkPaths.push_back("/Network/Library/Frameworks/");
        }
 
        // now merge sdk and library paths to make real search paths
@@ -2285,8 +2495,17 @@ void Options::parsePreCommandLineEnvironmentSettings()
 
        if (getenv("LD_PRINT_ORDER_FILE_STATISTICS") != NULL)
                fPrintOrderFileStatistics = true;
+
+       if (getenv("LD_SPLITSEGS_NEW_LIBRARIES") != NULL)
+               fSplitSegs = true;
+               
+       if (getenv("LD_NO_ENCRYPT") != NULL)
+               fEncryptable = false;
+               
+       sWarningsSideFilePath = getenv("LD_WARN_FILE");
 }
 
+
 // this is run after the command line is parsed
 void Options::parsePostCommandLineEnvironmentSettings()
 {
@@ -2303,6 +2522,27 @@ void Options::parsePostCommandLineEnvironmentSettings()
        if ( !fPrebind ) {
                fPrebind = ( getenv("LD_PREBIND") != NULL );
        }
+       
+       // allow build system to force on dead-code-stripping
+       if ( fDeadStrip == kDeadStripOff ) {
+               if ( getenv("LD_DEAD_STRIP") != NULL ) {
+                       switch (fOutputKind) {
+                               case Options::kDynamicLibrary:
+                               case Options::kDynamicExecutable:
+                               case Options::kDynamicBundle:
+                                       fDeadStrip = kDeadStripOn;
+                                       break;
+                               case Options::kObjectFile:
+                               case Options::kDyld:
+                               case Options::kStaticExecutable:
+                                       break;
+                       }
+               }
+       }
+       
+       // allow build system to force on -warn_commons
+       if ( getenv("LD_WARN_COMMONS") != NULL )
+               fWarnCommons = true;
 }
 
 void Options::reconfigureDefaults()
@@ -2332,7 +2572,7 @@ void Options::reconfigureDefaults()
                // if -macosx_version_min not used, try environment variable
                const char* envVers = getenv("MACOSX_DEPLOYMENT_TARGET");
                if ( envVers != NULL ) 
-                       setVersionMin(envVers);
+                       setMacOSXVersionMin(envVers);
                // if -macosx_version_min and environment variable not used assume current OS version
                if ( fReaderOptions.fVersionMin == ObjectFile::ReaderOptions::kMinUnset )
                        fReaderOptions.fVersionMin = ObjectFile::ReaderOptions::k10_5; // FIX FIX, this really should be a check of the OS version the linker is running on
@@ -2342,28 +2582,35 @@ void Options::reconfigureDefaults()
        switch ( fArchitecture ) {
                case CPU_TYPE_I386:
                        if ( fReaderOptions.fVersionMin < ObjectFile::ReaderOptions::k10_4 ) {
-                               //fprintf(stderr, "ld64 warning: -macosx_version_min should be 10.4 or later for i386\n");
+                               //warning("-macosx_version_min should be 10.4 or later for i386");
                                fReaderOptions.fVersionMin = ObjectFile::ReaderOptions::k10_4;
                        }
                        break;
                case CPU_TYPE_POWERPC64:
                        if ( fReaderOptions.fVersionMin < ObjectFile::ReaderOptions::k10_4 ) {
-                               //fprintf(stderr, "ld64 warning: -macosx_version_min should be 10.4 or later for ppc64\n");
+                               //warning("-macosx_version_min should be 10.4 or later for ppc64");
                                fReaderOptions.fVersionMin = ObjectFile::ReaderOptions::k10_4;
                        }
                        break;
                case CPU_TYPE_X86_64:
                        if ( fReaderOptions.fVersionMin < ObjectFile::ReaderOptions::k10_4 ) {
-                               //fprintf(stderr, "ld64 warning: -macosx_version_min should be 10.4 or later for x86_64\n");
+                               //warning("-macosx_version_min should be 10.4 or later for x86_64");
                                fReaderOptions.fVersionMin = ObjectFile::ReaderOptions::k10_4;
                        }
                        break;
        }
 
+       // disable implicit dylibs when targetting 10.3
+       // <rdar://problem/5451987> add option to disable implicit load commands for indirectly used public dylibs
+       if (  fReaderOptions.fVersionMin <= ObjectFile::ReaderOptions::k10_3 )
+               fReaderOptions.fImplicitlyLinkPublicDylibs = false;
+
+
        // determine if info for shared region should be added
        if ( fOutputKind == Options::kDynamicLibrary ) {
                if ( fReaderOptions.fVersionMin >= ObjectFile::ReaderOptions::k10_5 )
-                       fSharedRegionEligible = true;
+                       if ( fArchitecture != CPU_TYPE_ARM )
+                               fSharedRegionEligible = true;
        }
 
        // allow build system to force linker to ignore seg_addr_table
@@ -2371,23 +2618,47 @@ void Options::reconfigureDefaults()
                   fSegAddrTablePath = NULL;
 
        // check for base address specified externally
-       if ( (fSegAddrTablePath != NULL) &&  (fOutputKind == Options::kDynamicLibrary) ) 
+       if ( (fSegAddrTablePath != NULL) &&  (fOutputKind == Options::kDynamicLibrary) ) {
                parseSegAddrTable(fSegAddrTablePath, this->installPath());
+               // HACK to support seg_addr_table entries that are physical paths instead of install paths
+               if ( fBaseAddress == 0 ) {
+                       if ( strcmp(this->installPath(), "/usr/lib/libstdc++.6.dylib") == 0 ) 
+                               parseSegAddrTable(fSegAddrTablePath, "/usr/lib/libstdc++.6.0.4.dylib");
+                               
+                       else if ( strcmp(this->installPath(), "/usr/lib/libz.1.dylib") == 0 ) 
+                               parseSegAddrTable(fSegAddrTablePath, "/usr/lib/libz.1.2.3.dylib");
+                               
+                       else if ( strcmp(this->installPath(), "/usr/lib/libutil.dylib") == 0 ) 
+                               parseSegAddrTable(fSegAddrTablePath, "/usr/lib/libutil1.0.dylib");
+               }               
+       }
        
-
        // split segs only allowed for dylibs
        if ( fSplitSegs ) {
-               if ( fOutputKind != Options::kDynamicLibrary )
-                       fSplitSegs = false;
-               // split seg only supported for ppc and i386
-               switch ( fArchitecture ) {
-                       case CPU_TYPE_POWERPC:
-                       case CPU_TYPE_I386:
-                               break;
-                       default:
-                               fSplitSegs = false;
-                               fBaseAddress = 0;
-                               fBaseWritableAddress = 0;
+        // split seg only supported for ppc, i386, and arm.
+        switch ( fArchitecture ) {
+            case CPU_TYPE_POWERPC:
+            case CPU_TYPE_I386:
+                if ( fOutputKind != Options::kDynamicLibrary )
+                    fSplitSegs = false;
+                // make sure read and write segments are proper distance apart
+                if ( fSplitSegs && (fBaseWritableAddress-fBaseAddress != 0x10000000) )
+                    fBaseWritableAddress = fBaseAddress + 0x10000000;
+                break;
+            case CPU_TYPE_ARM:
+                if ( fOutputKind != Options::kDynamicLibrary ) {
+                    fSplitSegs = false;
+                               }
+                               else {
+                                       // make sure read and write segments are proper distance apart
+                                       if ( fSplitSegs && (fBaseWritableAddress-fBaseAddress != 0x08000000) )
+                                               fBaseWritableAddress = fBaseAddress + 0x08000000;
+                               }
+                break;
+            default:
+                fSplitSegs = false;
+                fBaseAddress = 0;
+                fBaseWritableAddress = 0;
                }
        }
 
@@ -2396,19 +2667,57 @@ void Options::reconfigureDefaults()
                switch ( fArchitecture ) {
                        case CPU_TYPE_POWERPC:
                        case CPU_TYPE_I386:
-                               if ( fReaderOptions.fVersionMin >= ObjectFile::ReaderOptions::k10_4 ) {
-                                       // only split seg dylibs are prebound
+                               if ( fReaderOptions.fVersionMin == ObjectFile::ReaderOptions::k10_4 ) {
+                                       // in 10.4 only split seg dylibs are prebound
                                        if ( (fOutputKind != Options::kDynamicLibrary) || ! fSplitSegs )
                                                fPrebind = false;
                                }
+                               else if ( fReaderOptions.fVersionMin >= ObjectFile::ReaderOptions::k10_5 ) {
+                                       // in 10.5 nothing is prebound
+                                       fPrebind = false;
+                               }
+                               else {
+                                       // in 10.3 and earlier only dylibs and main executables could be prebound
+                                       switch ( fOutputKind ) {
+                                               case Options::kDynamicExecutable:
+                                               case Options::kDynamicLibrary:
+                                                       // only main executables and dylibs can be prebound
+                                                       break;
+                                               case Options::kStaticExecutable:
+                                               case Options::kDynamicBundle:
+                                               case Options::kObjectFile:
+                                               case Options::kDyld:
+                                                       // disable prebinding for everything else
+                                                       fPrebind = false;
+                                                       break;
+                                       }
+                               }
                                break;
                        case CPU_TYPE_POWERPC64:
                        case CPU_TYPE_X86_64:
                                fPrebind = false;
                                break;
+            case CPU_TYPE_ARM:
+                               switch ( fOutputKind ) {
+                                       case Options::kDynamicExecutable:
+                                       case Options::kDynamicLibrary:
+                                               // only main executables and dylibs can be prebound
+                                               break;
+                                       case Options::kStaticExecutable:
+                                       case Options::kDynamicBundle:
+                                       case Options::kObjectFile:
+                                       case Options::kDyld:
+                                               // disable prebinding for everything else
+                                               fPrebind = false;
+                                               break;
+                               }
+                               break;
                }
        }
 
+       // only prebound images can be split-seg
+       if ( fSplitSegs && !fPrebind )
+               fSplitSegs = false;
 
        // figure out if module table is needed for compatibility with old ld/dyld
        if ( fOutputKind == Options::kDynamicLibrary ) {
@@ -2417,10 +2726,22 @@ void Options::reconfigureDefaults()
                        case CPU_TYPE_I386:             // ld_classic for 10.4.x requires a module table
                                if ( fReaderOptions.fVersionMin <= ObjectFile::ReaderOptions::k10_5 )
                                        fNeedsModuleTable = true;
+                               break;
+                       case CPU_TYPE_ARM:
+                               fNeedsModuleTable = true; // redo_prebinding requires a module table
+                               break;
                }
        }
        
+       // <rdar://problem/5366363> -r -x implies -S
+       if ( (fOutputKind == Options::kObjectFile) && (fLocalSymbolHandling == kLocalSymbolsNone) )
+               fReaderOptions.fDebugInfoStripping = ObjectFile::ReaderOptions::kDebugInfoNone; 
        
+       // only ARM main executables can be encrypted
+       if ( fOutputKind != Options::kDynamicExecutable )
+               fEncryptable = false;
+       if ( fArchitecture != CPU_TYPE_ARM )
+               fEncryptable = false;
 }
 
 void Options::checkIllegalOptionCombinations()
@@ -2454,8 +2775,8 @@ void Options::checkIllegalOptionCombinations()
                                break;
                        }
                }
-               if ( ! found && emitWarnings() )
-                       fprintf(stderr, "ld64 warning: -sub_umbrella %s does not match a supplied dylib\n", subUmbrella);
+               if ( ! found  )
+                       warning("-sub_umbrella %s does not match a supplied dylib", subUmbrella);
        }
 
        // unify -sub_library with dylibs
@@ -2476,8 +2797,8 @@ void Options::checkIllegalOptionCombinations()
                                break;
                        }
                }
-               if ( ! found && emitWarnings() )
-                       fprintf(stderr, "ld64 warning: -sub_library %s does not match a supplied dylib\n", subLibrary);
+               if ( ! found  )
+                       warning("-sub_library %s does not match a supplied dylib", subLibrary);
        }
 
        // sync reader options
@@ -2489,6 +2810,7 @@ void Options::checkIllegalOptionCombinations()
                switch (fArchitecture) {
                        case CPU_TYPE_I386:
                        case CPU_TYPE_POWERPC:
+            case CPU_TYPE_ARM:
                                if ( fStackAddr > 0xFFFFFFFF )
                                        throw "-stack_addr must be < 4G for 32-bit processes";
                                break;
@@ -2512,9 +2834,16 @@ void Options::checkIllegalOptionCombinations()
                                if ( fStackAddr == 0 ) {
                                        fStackAddr = 0xC0000000;
                                }
-                               if ( (fStackAddr > 0xB0000000) && ((fStackAddr-fStackSize) < 0xB0000000) && emitWarnings() )
-                                       fprintf(stderr, "ld64 warning: custom stack placement overlaps and will disable shared region\n");
+                               if ( (fStackAddr > 0xB0000000) && ((fStackAddr-fStackSize) < 0xB0000000)  )
+                                       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 ( fStackAddr == 0 )
+                                       fStackAddr = 0x30000000;
+                if ( fStackAddr > 0x40000000)
+                    throw "-stack_addr must be < 1G for arm";
                        case CPU_TYPE_POWERPC64:
                        case CPU_TYPE_X86_64:
                                if ( fStackAddr == 0 ) {
@@ -2597,7 +2926,7 @@ void Options::checkIllegalOptionCombinations()
                // never export .eh symbols
                const int len = strlen(name);
                if ( (strcmp(&name[len-3], ".eh") == 0) || (strncmp(name, ".objc_category_name_", 20) == 0) ) 
-                       fprintf(stderr, "ld64 warning: ignoring %s in export list\n", name);
+                       warning("ignoring %s in export list", name);
                else
                        fInitialUndefines.push_back(name);
                if ( strncmp(name, ".objc_class_name_", 17) == 0 ) {
@@ -2605,6 +2934,7 @@ void Options::checkIllegalOptionCombinations()
                        switch (fArchitecture) {
                                case CPU_TYPE_POWERPC64:
                                case CPU_TYPE_X86_64:
+                           case CPU_TYPE_ARM:
                                        char* temp;
                                        asprintf(&temp, "_OBJC_CLASS_$_%s", &name[17]);
                                        impliedExports.push_back(temp);
@@ -2650,6 +2980,7 @@ void Options::checkIllegalOptionCombinations()
                switch (fArchitecture) {
                        case CPU_TYPE_I386:
                        case CPU_TYPE_POWERPC:
+            case CPU_TYPE_ARM:
                                // first 4KB for 32-bit architectures
                                fZeroPageSize = 0x1000;
                                break;
@@ -2686,12 +3017,12 @@ void Options::checkIllegalOptionCombinations()
 
        // -dead_strip and -r are incompatible
        if ( (fDeadStrip != kDeadStripOff) && (fOutputKind == Options::kObjectFile) )
-               throw "-r and -dead_strip cannot be used together\n";
+               throw "-r and -dead_strip cannot be used together";
 
        // can't use -rpath unless targeting 10.5 or later
        if ( fRPaths.size() > 0 ) {
                if ( fReaderOptions.fVersionMin < ObjectFile::ReaderOptions::k10_5 ) 
-                       throw "-rpath can only be used when targeting Mac OS X 10.5 or later\n";
+                       throw "-rpath can only be used when targeting Mac OS X 10.5 or later";
                switch ( fOutputKind ) {
                        case Options::kDynamicExecutable:
                        case Options::kDynamicLibrary:
@@ -2766,11 +3097,24 @@ void Options::checkForClassic(int argc, const char* argv[])
                switch ( fArchitecture ) {
                case CPU_TYPE_POWERPC:
                case CPU_TYPE_I386:
+        case CPU_TYPE_ARM:
 //                     if ( staticFound && (rFound || !creatingMachKernel) ) {
                        if ( staticFound && !newLinker ) {
                                // this environment variable will disable use of ld_classic for -static links
-                               if ( getenv("LD_NO_CLASSIC_LINKER_STATIC") == NULL )
+                               if ( getenv("LD_NO_CLASSIC_LINKER_STATIC") == NULL ) {
+                                       // ld_classic does not support -aspen_version_min, so change
+                                       for(int j=0; j < argc; ++j) {
+                                               if ( (strcmp(argv[j], "-aspen_version_min") == 0)
+                                                        || (strcmp(argv[j], "-iphone_version_min") == 0) 
+                                                        || (strcmp(argv[j], "-iphoneos_version_min") == 0) ) {
+                                                       argv[j] = "-macosx_version_min";
+                                                       if ( j < argc-1 )
+                                                               argv[j+1] = "10.5";
+                                                       break;
+                                               }
+                                       }
                                        this->gotoClassicLinker(argc, argv);
+                               }
                        }
                        break;
                }
old mode 100644 (file)
new mode 100755 (executable)
index 3670756..d185848
 
 #include "ObjectFile.h"
 
-void throwf (const char* format, ...) __attribute__ ((noreturn));
+extern void throwf (const char* format, ...) __attribute__ ((noreturn));
+extern void warning(const char* format, ...);
 
 class DynamicLibraryOptions
 {
 public:
-       DynamicLibraryOptions() : fWeakImport(false), fReExport(false), fBundleLoader(false) {}
+       DynamicLibraryOptions() : fWeakImport(false), fReExport(false), fBundleLoader(false), fLazyLoad(false) {}
 
        bool            fWeakImport;
        bool            fReExport;
        bool            fBundleLoader;
+       bool            fLazyLoad;
 };
 
 //
@@ -120,7 +122,9 @@ public:
        const char*                                                     getOutputFilePath();
        std::vector<FileInfo>&                          getInputFiles();
 
-       cpu_type_t                                      architecture();
+       cpu_type_t                                      architecture() { return fArchitecture; }
+       bool                                            preferSubArchitecture() { return fHasPreferredSubType; }
+       cpu_subtype_t                           subArchitecture() { return fSubArchitecture; }
        OutputKind                                      outputKind();
        bool                                            prebind();
        bool                                            bindAtLoad();
@@ -132,10 +136,12 @@ public:
        const char*                                     entryName();                    // only for kDynamicExecutable or kStaticExecutable
        const char*                                     executablePath();
        uint64_t                                        baseAddress();
-       bool                                            keepPrivateExterns();   // only for kObjectFile
-       bool                                            interposable();                 // only for kDynamicLibrary
-       bool                                            needsModuleTable();             // only for kDynamicLibrary
+       bool                                            keepPrivateExterns();                   // only for kObjectFile
+       bool                                            needsModuleTable();                             // only for kDynamicLibrary
+       bool                                            interposable(const char* name);
        bool                                            hasExportRestrictList();
+       bool                                            hasExportMaskList();
+       bool                                            hasWildCardExportRestrictList();
        bool                                            allGlobalsAreDeadStripRoots();
        bool                                            shouldExport(const char*);
        bool                                            ignoreOtherArchInputFiles();
@@ -186,6 +192,7 @@ public:
        bool                                            saveTempFiles() { return fSaveTempFiles; }
        const std::vector<const char*>&   rpaths() { return fRPaths; }
        bool                                            readOnlyx86Stubs() { return fReadOnlyx86Stubs; }
+       bool                                            slowx86Stubs() { return fReaderOptions.fSlowx86Stubs; }
        std::vector<DylibOverride>&     dylibOverrides() { return fDylibOverrides; }
        const char*                                     generatedMapPath() { return fMapPath; }
        bool                                            positionIndependentExecutable() { return fPositionIndependentExecutable; }
@@ -195,7 +202,11 @@ public:
        bool                                            someAllowedUndefines() { return (fAllowedUndefined.size() != 0); }
        LocalSymbolHandling                     localSymbolHandling() { return fLocalSymbolHandling; }
        bool                                            keepLocalSymbol(const char* symbolName);
-       bool                                            emitWarnings() { return !fSuppressWarnings; }
+       bool                                            allowTextRelocs() { return fAllowTextRelocs; }
+       bool                                            warnAboutTextRelocs() { return fWarnTextRelocs; }
+       bool                                            usingLazyDylibLinking() { return fUsingLazyDylibLinking; }
+       bool                                            verbose() { return fVerbose; }
+       bool                                            makeEncryptable() { return fEncryptable; }
 
 private:
        class CStringEquals
@@ -207,15 +218,17 @@ private:
        typedef __gnu_cxx::hash_set<const char*, __gnu_cxx::hash<const char*>, CStringEquals>  NameSet;
        enum ExportMode { kExportDefault, kExportSome, kDontExportSome };
        enum LibrarySearchMode { kSearchDylibAndArchiveInEachDir, kSearchAllDirsForDylibsThenAllDirsForArchives };
+       enum InterposeMode { kInterposeNone, kInterposeAllExternal, kInterposeSome };
 
        class SetWithWildcards {
        public:
                void                                    insert(const char*);
                bool                                    contains(const char*);
+               bool                                    hasWildCards()  { return !fWildCard.empty(); }
                NameSet::iterator               regularBegin()  { return fRegular.begin(); }
                NameSet::iterator               regularEnd()    { return fRegular.end(); }
        private:
-               bool                                    hasWildCards(const char*);
+               static bool                             hasWildCards(const char*);
                bool                                    wildCardMatch(const char* pattern, const char* candidate);
                bool                                    inCharRange(const char*& range, unsigned char c);
 
@@ -228,7 +241,7 @@ private:
        void                                            checkIllegalOptionCombinations();
        void                                            buildSearchPaths(int argc, const char* argv[]);
        void                                            parseArch(const char* architecture);
-       FileInfo                                        findLibrary(const char* rootName);
+       FileInfo                                        findLibrary(const char* rootName, bool dylibsOnly=false);
        FileInfo                                        findFramework(const char* frameworkName);
        FileInfo                                        findFramework(const char* rootName, const char* suffix);
        bool                                            checkForFile(const char* format, const char* dir, const char* rootName,
@@ -245,7 +258,8 @@ private:
        void                                            parsePreCommandLineEnvironmentSettings();
        void                                            parsePostCommandLineEnvironmentSettings();
        void                                            setUndefinedTreatment(const char* treatment);
-       void                                            setVersionMin(const char* version);
+       void                                            setMacOSXVersionMin(const char* version);
+       void                                            setIPhoneVersionMin(const char* version);
        void                                            setWeakReferenceMismatchTreatment(const char* treatment);
        void                                            addDylibOverride(const char* paths);
        void                                            addSectionAlignment(const char* segment, const char* section, const char* alignment);
@@ -263,14 +277,16 @@ private:
        const char*                                                     fOutputFile;
        std::vector<Options::FileInfo>          fInputFiles;
        cpu_type_t                                                      fArchitecture;
+       cpu_subtype_t                                           fSubArchitecture;
        OutputKind                                                      fOutputKind;
+       bool                                                            fHasPreferredSubType;
        bool                                                            fPrebind;
        bool                                                            fBindAtLoad;
        bool                                                            fKeepPrivateExterns;
-       bool                                                            fInterposable;
        bool                                                            fNeedsModuleTable;
        bool                                                            fIgnoreOtherArchFiles;
        bool                                                            fForceSubtypeAll;
+       InterposeMode                                           fInterposeMode;
        DeadStripMode                                           fDeadStrip;
        NameSpace                                                       fNameSpace;
        uint32_t                                                        fDylibCompatVersion;
@@ -283,6 +299,7 @@ private:
        bool                                                            fSplitSegs;
        SetWithWildcards                                        fExportSymbols;
        SetWithWildcards                                        fDontExportSymbols;
+       SetWithWildcards                                        fInterposeList;
        ExportMode                                                      fExportMode;
        LibrarySearchMode                                       fLibrarySearchMode;
        UndefinedTreatment                                      fUndefinedTreatment;
@@ -325,7 +342,10 @@ private:
        bool                                                            fPositionIndependentExecutable;
        bool                                                            fMaxMinimumHeaderPad;
        bool                                                            fDeadStripDylibs;
-       bool                                                            fSuppressWarnings;
+       bool                                                            fAllowTextRelocs;
+       bool                                                            fWarnTextRelocs;
+       bool                                                            fUsingLazyDylibLinking;
+       bool                                                            fEncryptable;
        std::vector<const char*>                        fInitialUndefines;
        NameSet                                                         fAllowedUndefined;
        NameSet                                                         fWhyLive;
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index a2a56b9..49f05c4
  *
  * @APPLE_LICENSE_HEADER_END@
  */
+// start temp HACK for cross builds
+extern "C" double log2 ( double );
+#define __MATH__
+// end temp HACK for cross builds
+
+
 #include <stdlib.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -33,7 +40,6 @@
 #include <mach/vm_statistics.h>
 #include <mach/mach_init.h>
 #include <mach/mach_host.h>
-#include <mach-o/fat.h>
 #include <dlfcn.h>
 
 #include <string>
 #include <dlfcn.h>
 #include <AvailabilityMacros.h>
 
+#include "configure.h"
 #include "Options.h"
 
 #include "ObjectFile.h"
 
 #include "MachOReaderRelocatable.hpp"
-#include "MachOReaderArchive.hpp"
+#include "ArchiveReader.hpp"
 #include "MachOReaderDylib.hpp"
 #include "MachOWriterExecutable.hpp"
 
-#define LLVM_SUPPORT 0
  
-#if LLVM_SUPPORT
-#include "LLVMReader.hpp"
+#if LTO_SUPPORT
+#include "LTOReader.hpp"
 #endif
 
+
 #include "OpaqueSection.hpp"
 
 
@@ -235,7 +242,8 @@ private:
        void                            addAtoms(std::vector<class ObjectFile::Atom*>& atoms);
        void                            buildAtomList();
        void                            processDylibs();
-       void                            updateContraints(ObjectFile::Reader* reader);
+       void                            markDead(ObjectFile::Atom* atom);
+       void                            updateConstraints(ObjectFile::Reader* reader);
        void                            loadAndResolve();
        void                            processDTrace();
        void                            checkObjC();
@@ -255,8 +263,9 @@ private:
        static const char*      truncateStabString(const char* str);
        void                            collectDebugInfo();
        void                            writeOutput();
-       ObjectFile::Atom*       entryPoint();
+       ObjectFile::Atom*       entryPoint(bool orInit);
        ObjectFile::Atom*       dyldHelper();
+       ObjectFile::Atom*       dyldLazyLibraryHelper();
        const char*                     assureFullPath(const char* path);
        void                            markLive(ObjectFile::Atom& atom, Linker::WhyLiveBackChain* previous);
        void                            collectStabs(ObjectFile::Reader* reader, std::map<const class ObjectFile::Atom*, uint32_t>& atomOrdinals);
@@ -272,7 +281,7 @@ private:
        
        void                                                                    resolve(ObjectFile::Reference* reference);
        void                                                                    resolveFrom(ObjectFile::Reference* reference);
-       std::vector<class ObjectFile::Atom*>*   addJustInTimeAtoms(const char* name);
+       std::vector<class ObjectFile::Atom*>*   addJustInTimeAtoms(const char* name, bool dylibsOnly=false);
        void                                                                    addJustInTimeAtomsAndMarkLive(const char* name);
 
        ObjectFile::Reader*     addDylib(ObjectFile::Reader* reader, const Options::FileInfo& info, uint64_t mappedLen);
@@ -285,17 +294,26 @@ private:
        class SymbolTable
        {
        public:
+               typedef __gnu_cxx::hash_map<const char*, ObjectFile::Atom*, __gnu_cxx::hash<const char*>, CStringEquals> Mapper;
+
                                                        SymbolTable(Linker&);
                void                            require(const char* name);
                bool                            add(ObjectFile::Atom& atom);
                ObjectFile::Atom*       find(const char* name);
                unsigned int            getRequireCount() { return fRequireCount; }
                void                            getNeededNames(bool andWeakDefintions, std::vector<const char*>& undefines);
-               typedef __gnu_cxx::hash_map<const char*, ObjectFile::Atom*, __gnu_cxx::hash<const char*>, CStringEquals> Mapper;
+               bool                            hasExternalTentativeDefinitions() { return fHasExternalTentativeDefinitions; }
+               bool                            hasExternalWeakDefinitions() { return fHasExternalWeakDefinitions; }
+               void                            setHasExternalWeakDefinitions() { fHasExternalWeakDefinitions = true; }
+               Mapper::iterator        begin() { return fTable.begin(); }
+               Mapper::iterator        end()   { return fTable.end(); }
+
        private:
                Linker&                         fOwner;
                Mapper                          fTable;
                unsigned int            fRequireCount;
+               bool                            fHasExternalTentativeDefinitions;
+               bool                            fHasExternalWeakDefinitions;
        };
 
        class AtomSorter
@@ -386,7 +404,7 @@ private:
 
 Linker::Linker(int argc, const char* argv[])
        : fOptions(argc, argv), fGlobalSymbolTable(*this), fNextInputOrdinal(1), fOutputFile(NULL), fBundleLoaderReader(NULL), 
-         fCreateUUID(false), fCanScatter(true),
+         fCreateUUID(fOptions.outputKind() != Options::kObjectFile), fCanScatter(true),
          fArchitecture(0), fArchitectureInferred(false), fDirectLibrariesComplete(false), fBiggerThanTwoGigOutput(false),
          fOutputFileSize(0), fTotalZeroFillSize(0), fTotalSize(0), fTotalObjectSize(0),
          fTotalArchiveSize(0),  fTotalObjectLoaded(0), fTotalArchivesLoaded(0), fTotalDylibsLoaded(0),
@@ -416,6 +434,9 @@ Linker::Linker(int argc, const char* argv[])
                case CPU_TYPE_X86_64:
                        fArchitectureName = "x86_64";
                        break;
+               case CPU_TYPE_ARM:
+                       fArchitectureName = "arm";
+                       break;
                default:
                        fArchitectureName = "unknown architecture";
                        break;
@@ -450,27 +471,31 @@ cpu_type_t Linker::inferArchitecture()
                        ::close(fd);
                        if ( amount >= (ssize_t)sizeof(buffer) ) {
                                if ( mach_o::relocatable::Reader<ppc>::validFile(buffer) ) {
-                                       //fprintf(stderr, "ld: warning -arch not used, infering -arch ppc based on %s\n", it->path);
+                                       //warning("-arch not used, infering -arch ppc based on %s", it->path);
                                        return CPU_TYPE_POWERPC;
                                }
                                else if ( mach_o::relocatable::Reader<ppc64>::validFile(buffer) ) {
-                                       //fprintf(stderr, "ld: warning -arch not used, infering -arch ppc64 based on %s\n", it->path);
+                                       //warning("-arch not used, infering -arch ppc64 based on %s", it->path);
                                        return CPU_TYPE_POWERPC64;
                                }
                                else if ( mach_o::relocatable::Reader<x86>::validFile(buffer) ) {
-                                       //fprintf(stderr, "ld: warning -arch not used, infering -arch i386 based on %s\n", it->path);
+                                       //warning("-arch not used, infering -arch i386 based on %s", it->path);
                                        return CPU_TYPE_I386;
                                }
                                else if ( mach_o::relocatable::Reader<x86_64>::validFile(buffer) ) {
-                                       //fprintf(stderr, "ld: warning -arch not used, infering -arch x86_64 based on %s\n", it->path);
+                                       //warning("-arch not used, infering -arch x86_64 based on %s", it->path);
                                        return CPU_TYPE_X86_64;
                                }
+                               else if ( mach_o::relocatable::Reader<arm>::validFile(buffer) ) {
+                                       //warning("-arch not used, infering -arch arm based on %s", it->path);
+                                       return CPU_TYPE_ARM;
+                               }
                        }
                }
        }
 
        // no thin .o files found, so default to same architecture this was built as
-       fprintf(stderr, "ld: warning -arch not specified\n");
+       warning("-arch not specified");
 #if __ppc__
        return CPU_TYPE_POWERPC;
 #elif __i386__
@@ -479,6 +504,8 @@ cpu_type_t Linker::inferArchitecture()
        return CPU_TYPE_POWERPC64;
 #elif __x86_64__
        return CPU_TYPE_X86_64;
+#elif __arm__
+       return CPU_TYPE_ARM;
 #else
        #error unknown default architecture
 #endif
@@ -534,34 +561,48 @@ void Linker::loadAndResolve()
 
 void Linker::optimize()
 {
+       // give each reader a chance to do any optimizations
        std::vector<class ObjectFile::Atom*> newAtoms;
-
-       const int readerCount = fInputFiles.size();
-       for (int i=0; i < readerCount; ++i) {
-               fInputFiles[i]->optimize(fAllAtoms, newAtoms, fNextInputOrdinal);
+       std::vector<const char *> additionalUndefines;
+       for (std::vector<class ObjectFile::Reader*>::iterator it=fInputFiles.begin(); it != fInputFiles.end(); it++) {
+               (*it)->optimize(fAllAtoms, newAtoms, additionalUndefines, fNextInputOrdinal, fOutputFile, 
+                        fOptions.allGlobalsAreDeadStripRoots(), (int)fOptions.outputKind(), fOptions.verbose(),
+                       fOptions.saveTempFiles(), fOptions.getOutputFilePath(), fOptions.positionIndependentExecutable(),
+                       fOptions.allowTextRelocs());
        }
-       // note: When writer start generating stubs and non-lazy-pointers for all architecture, do not insert
-       // newAtoms into fGlobalSymbolTable. Instead directly insert them in fAllAtoms and set their order appropriately.
+       
+       // add all newly created atoms to fAllAtoms and update symbol table
        this->addAtoms(newAtoms);
 
-       // Some of the optimized atoms may not have identified section properly, if they
-       // were created before optimizer produces corrosponding real atom. Here, input
-       // file readers are not able to patch it themselves because Section::find() is
-       // linker specific.
-       for(std::vector<class ObjectFile::Atom*>::iterator itr = fAllAtoms.begin();
-               itr != fAllAtoms.end(); ++itr) {
-
+       // Make sure all atoms have a section.  Atoms that were not originally in a mach-o file could
+       // not have their section set until now.
+       for(std::vector<class ObjectFile::Atom*>::iterator itr = fAllAtoms.begin(); itr != fAllAtoms.end(); ++itr) {
                ObjectFile::Atom *atom = *itr;
-               if (atom->getSectionName() && !atom->getSection())
+               if ( atom->getSection() == NULL )
                        atom->setSection(Section::find(atom->getSectionName(), atom->getSegment().getName(), atom->isZeroFill()));
        }
 
+       // resolve new undefines
+       for(std::vector<const char*>::iterator riter = additionalUndefines.begin(); riter != additionalUndefines.end(); ++riter) {
+               const char *targetName = *riter;
+               //fprintf(stderr, "LTO additional undefine: %s\n", targetName);
+               ObjectFile::Atom* target = fGlobalSymbolTable.find(targetName);
+               if ( target == NULL) {
+                       // mark that this symbol is needed
+                       fGlobalSymbolTable.require(targetName);
+                       // try to find it in some library
+                       this->addJustInTimeAtoms(targetName);
+               }
+       }
+
        if ( fOptions.deadStrip() != Options::kDeadStripOff ) {
                fLiveAtoms.clear();
-        deadStripResolve();
-    }
-    else
-        resolveReferences();
+               this->deadStripResolve();
+       }
+       else {
+               this->checkUndefines();
+               this->resolveReferences();
+       }
 }
 
 void Linker::link()
@@ -695,11 +736,20 @@ inline void Linker::addAtom(ObjectFile::Atom& atom)
        ObjectFile::Atom::Scope scope = atom.getScope();
        const char* name = atom.getName();
        if ( (scope != ObjectFile::Atom::scopeTranslationUnit) && (name != NULL) ) {
-               // update scope based on export list (possible that globals are downgraded to private_extern)
-               if ( (scope == ObjectFile::Atom::scopeGlobal) && fOptions.hasExportRestrictList() ) {
-                       bool doExport = fOptions.shouldExport(name);
-                       if ( !doExport ) {
-                               atom.setScope(ObjectFile::Atom::scopeLinkageUnit);
+               // update scope based on export list 
+               if ( fOptions.hasExportRestrictList() ) {
+                       if ( scope == ObjectFile::Atom::scopeGlobal ) {
+                               // check for globals that are downgraded to hidden
+                               bool doExport = fOptions.shouldExport(name);
+                               if ( !doExport ) {
+                                       atom.setScope(ObjectFile::Atom::scopeLinkageUnit);
+                               }
+                       }
+                       else if ( scope == ObjectFile::Atom::scopeLinkageUnit ) {
+                               // check for hiddens that were requested to be exported
+                               if (  fOptions.hasExportMaskList() && fOptions.shouldExport(name) ) {
+                                       warning("cannot export hidden symbol %s from %s", name, atom.getFile()->getPath());
+                               }
                        }
                }
                // add to symbol table
@@ -711,61 +761,66 @@ inline void Linker::addAtom(ObjectFile::Atom& atom)
                atom.setSection(Section::find(atom.getSectionName(), atom.getSegment().getName(), atom.isZeroFill()));
 }
 
-void Linker::updateContraints(ObjectFile::Reader* reader)
+
+void Linker::markDead(ObjectFile::Atom* atom)
+{
+       fDeadAtoms.insert(atom);
+       //
+       // The kGroupSubordinate reference kind is used to model group comdat.  
+       // The "signature" atom in the group has a kGroupSubordinate reference to
+       // all other members of the group.  So, if the signature atom is 
+       // coalesced away, all other atoms in the group should also be removed.  
+       //
+       std::vector<class 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() == 2 /*kGroupSubordinate*/ ) {      // FIX FIX
+                       ObjectFile::Atom* targetAtom = &(ref->getTarget());
+                       if ( targetAtom == NULL ) {
+                               warning("%s has a group reference to %s but is not bound", atom->getDisplayName(), ref->getTargetName());
+                       }
+                       else {
+                               if ( targetAtom->getScope() != ObjectFile::Atom::scopeTranslationUnit ) {
+                                       // ok for .eh symbols to be not static in -r mode
+                                       if ( (fOptions.outputKind() != Options::kObjectFile) || (strcmp(targetAtom->getSectionName(), "__eh_frame") != 0) )
+                                               warning("%s is in a comdat group but its scope is not static", targetAtom->getDisplayName());
+                               }
+                               this->markDead(targetAtom);
+                       }
+               }
+       }
+}
+
+void Linker::updateConstraints(ObjectFile::Reader* reader)
 {
        // check objc objects were compiled compatibly
        ObjectFile::Reader::ObjcConstraint objcAddition = reader->getObjCConstraint();
        if ( reader->getInstallPath() == NULL ) {
                // adding a .o file
-               switch ( fCurrentObjCConstraint ) {
+               switch ( objcAddition ) {
                        case ObjectFile::Reader::kObjcNone:
-                               fCurrentObjCConstraint = objcAddition;
                                break;
                        case ObjectFile::Reader::kObjcRetainRelease:
+                               if ( fCurrentObjCConstraint == ObjectFile::Reader::kObjcGC )
+                                       throwf("%s built with incompatible Garbage Collection settings to link with previous .o files", reader->getPath());
+                               fCurrentObjCConstraint = ObjectFile::Reader::kObjcRetainRelease;
+                               break;
                        case ObjectFile::Reader::kObjcRetainReleaseOrGC:
+                               if ( fCurrentObjCConstraint == ObjectFile::Reader::kObjcNone )
+                                       fCurrentObjCConstraint = ObjectFile::Reader::kObjcRetainReleaseOrGC;
+                               break;
                        case ObjectFile::Reader::kObjcGC:
-                               if ( (fCurrentObjCConstraint != objcAddition) && (objcAddition != ObjectFile::Reader::kObjcNone) ) 
-                                       throwf("%s built with different Garbage Collection settings", reader->getPath());
+                               if ( fCurrentObjCConstraint == ObjectFile::Reader::kObjcRetainRelease )
+                                       throwf("%s built with incompatible Garbage Collection settings to link with previous .o files", reader->getPath());
+                               fCurrentObjCConstraint = ObjectFile::Reader::kObjcGC;
                                break;
                }
        }
        if ( reader->objcReplacementClasses() )
                fObjcReplacmentClasses = true;
 
-       // check cpu sub-types
-       ObjectFile::Reader::CpuConstraint  cpuAddition = reader->getCpuConstraint();
-       switch ( fCurrentCpuConstraint ) {
-               case ObjectFile::Reader::kCpuAny:
-                       fCurrentCpuConstraint = cpuAddition;
-                       break;
-               case ObjectFile::Reader::kCpuG3:
-                       switch ( cpuAddition ) {
-                               case ObjectFile::Reader::kCpuAny:
-                               case ObjectFile::Reader::kCpuG3:
-                                       break;
-                               case ObjectFile::Reader::kCpuG4:
-                               case ObjectFile::Reader::kCpuG5:
-                                       // previous file for G3 this one is more contrained, use it
-                                       fCurrentCpuConstraint = cpuAddition;
-                                       break;
-                       }
-                       break;
-               case ObjectFile::Reader::kCpuG4:
-                       switch ( cpuAddition ) {
-                               case ObjectFile::Reader::kCpuAny:
-                               case ObjectFile::Reader::kCpuG3:
-                               case ObjectFile::Reader::kCpuG4:
-                                       break;
-                               case ObjectFile::Reader::kCpuG5:
-                                       // previous file for G5 this one is more contrained, use it
-                                       fCurrentCpuConstraint = cpuAddition;
-                                       break;
-                       }
-                       break;
-               case ObjectFile::Reader::kCpuG5:
-                       // G5 can run everything
-                       break;
-       }
+       // check cpu sub-types for stricter sub-type
+       fCurrentCpuConstraint = (ObjectFile::Reader::CpuConstraint)reader->updateCpuConstraint(fCurrentCpuConstraint);
 }
 
 inline void Linker::addAtoms(std::vector<class ObjectFile::Atom*>& atoms)
@@ -782,7 +837,7 @@ inline void Linker::addAtoms(std::vector<class ObjectFile::Atom*>& atoms)
                        if ( std::find(fReadersThatHaveSuppliedAtoms.begin(), fReadersThatHaveSuppliedAtoms.end(), reader)
                                        == fReadersThatHaveSuppliedAtoms.end() ) {
                                fReadersThatHaveSuppliedAtoms.push_back(reader);
-                               updateContraints(reader);                               
+                               updateConstraints(reader);                              
                        }       
                }
                this->addAtom(**it);
@@ -956,11 +1011,53 @@ void Linker::checkUndefines()
                if ( doError ) 
                        throw "symbol(s) not found";
        }
+       
+       // for each tentative definition in symbol table look for dylib that exports same symbol name
+       if ( fGlobalSymbolTable.hasExternalTentativeDefinitions() ) {
+               for (SymbolTable::Mapper::iterator it=fGlobalSymbolTable.begin(); it != fGlobalSymbolTable.end(); ++it) {
+                       ObjectFile::Atom* atom = it->second;
+                       if ( (atom != NULL) && (atom->getDefinitionKind()==ObjectFile::Atom::kTentativeDefinition) 
+                               && (atom->getScope() == ObjectFile::Atom::scopeGlobal) ) {
+                               // look for dylibs that export same name as used by global tentative definition
+                               addJustInTimeAtoms(atom->getName(), true);
+                       }
+               }
+       }
+       
+       // if we have no weak symbols, see if we override some weak symbol in some dylib 
+       if ( !fGlobalSymbolTable.hasExternalWeakDefinitions() ) {
+               bool done = false;
+               for (SymbolTable::Mapper::iterator it=fGlobalSymbolTable.begin(); !done && (it != fGlobalSymbolTable.end()); ++it) {
+                       ObjectFile::Atom* atom = it->second;
+                       if ( (atom != NULL) && (atom->getDefinitionKind()==ObjectFile::Atom::kRegularDefinition) 
+                               && (atom->getScope() == ObjectFile::Atom::scopeGlobal) ) {
+                               const char* name = atom->getName();
+                               //fprintf(stderr, "looking for dylibs with a weak %s\n", name);
+                               // look for dylibs with weak exports of the same name 
+                               for (InstallNameToReader::iterator it=fDylibMap.begin(); it != fDylibMap.end(); it++) {
+                                       ObjectFile::Reader* reader = it->second;
+                                       if ( reader->hasWeakExternals() ) {
+                                               std::vector<class ObjectFile::Atom*>* atoms = reader->getJustInTimeAtomsFor(name);
+                                               if ( atoms != NULL ) {
+                                                       //fprintf(stderr, "addJustInTimeAtoms(%s) => found in file %s\n", name, reader->getPath() );
+                                                       // if this is a weak definition in a dylib
+                                                       if ( (atoms->at(0)->getDefinitionKind() == ObjectFile::Atom::kExternalWeakDefinition) ) {
+                                                               fGlobalSymbolTable.setHasExternalWeakDefinitions();
+                                                               done = true;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       
 }
 
 
 
-std::vector<class ObjectFile::Atom*>* Linker::addJustInTimeAtoms(const char* name)
+std::vector<class ObjectFile::Atom*>* Linker::addJustInTimeAtoms(const char* name, bool dylibsOnly)
 {
        // when creating final linked image, writer gets first chance
        if ( fOptions.outputKind() != Options::kObjectFile ) {
@@ -979,20 +1076,23 @@ std::vector<class ObjectFile::Atom*>* Linker::addJustInTimeAtoms(const char* nam
                        // if this reader is a static archive that has the symbol we need, pull in all atoms in that module
                        // if this reader is a dylib that exports the symbol we need, have it synthesize an atom for us.
                        //fprintf(stderr, "addJustInTimeAtoms(%s), looking in reader %s\n", name, reader->getPath() );
-                       std::vector<class ObjectFile::Atom*>* atoms = reader->getJustInTimeAtomsFor(name);
-                       if ( atoms != NULL ) {
-                               this->addAtoms(*atoms);
-                               //fprintf(stderr, "addJustInTimeAtoms(%s) => found in file %s\n", name, reader->getPath() );
-                               if ( fOptions.readerOptions().fTraceArchives ) {
-                                       logArchive(reader);
-                               }
-                               // if this is a weak definition in a dylib
-                               if ( (atoms->size() == 1) && (reader->getInstallPath() != NULL) && (atoms->at(0)->getDefinitionKind() == ObjectFile::Atom::kExternalWeakDefinition) ) {
-                                       // keep looking for a non-weak definition
-                               }
-                               else {
-                                       // found a definition, no need to search anymore
-                                       return atoms;  
+                       bool isDylibReader = (reader->getInstallPath() != NULL);
+                       if ( !dylibsOnly || isDylibReader ) {
+                               std::vector<class ObjectFile::Atom*>* atoms = reader->getJustInTimeAtomsFor(name);
+                               if ( atoms != NULL ) {
+                                       this->addAtoms(*atoms);
+                                       //fprintf(stderr, "addJustInTimeAtoms(%s) => found in file %s\n", name, reader->getPath() );
+                                       if ( !isDylibReader && fOptions.readerOptions().fTraceArchives ) {
+                                               logArchive(reader);
+                                       }
+                                       // if this is a weak definition in a dylib
+                                       if ( isDylibReader && (atoms->size() == 1) && (atoms->at(0)->getDefinitionKind() == ObjectFile::Atom::kExternalWeakDefinition) ) {
+                                               // keep looking for a non-weak definition
+                                       }
+                                       else {
+                                               // found a definition, no need to search anymore
+                                               return atoms;  
+                                       }
                                }
                        }
                }
@@ -1034,10 +1134,13 @@ std::vector<class ObjectFile::Atom*>* Linker::addJustInTimeAtoms(const char* nam
                }
        }
 
-       // when creating .o file, writer goes last (this is so any static archives will be searched above)
+       // writer creates a proxy in two cases:
+       // 1) ld -r is being used to create a .o file 
+       // 2) -undefined dynamic_lookup is being used
+       // 3) -U _foo is being used
        if (    (fOptions.outputKind() == Options::kObjectFile) 
-               ||  (fOptions.undefinedTreatment() != Options::kUndefinedError)
-               ||      fOptions.someAllowedUndefines() ) {
+               ||  ((fOptions.undefinedTreatment() != Options::kUndefinedError) && !dylibsOnly)
+               ||      (fOptions.someAllowedUndefines() && !dylibsOnly) ) {
                ObjectFile::Atom* atom = fOutputFile->getUndefinedProxyAtom(name);
                if ( atom != NULL ) {
                        this->addAtom(*atom);
@@ -1249,7 +1352,7 @@ void Linker::addLiveRoot(const char* name)
 void Linker::deadStripResolve()
 {
        // add main() to live roots
-       ObjectFile::Atom* entryPoint = this->entryPoint();
+       ObjectFile::Atom* entryPoint = this->entryPoint(false);
        if ( entryPoint != NULL )
                fLiveRootAtoms.insert(entryPoint);
 
@@ -1258,11 +1361,30 @@ void Linker::deadStripResolve()
        if ( dyldHelper != NULL )
                fLiveRootAtoms.insert(dyldHelper);
 
+       // if using lazy dylib loading, add dyld_lazy_dylib_stub_binding_helper() to live roots
+       if ( fOptions.usingLazyDylibLinking() ) {
+               ObjectFile::Atom* dyldLazyDylibHelper = this->dyldLazyLibraryHelper();
+               if ( dyldLazyDylibHelper != NULL )
+                       fLiveRootAtoms.insert(dyldLazyDylibHelper);
+       }
+       
        // add -exported_symbols_list, -init, and -u entries to live roots
        std::vector<const char*>& initialUndefines = fOptions.initialUndefines();
        for (std::vector<const char*>::iterator it=initialUndefines.begin(); it != initialUndefines.end(); it++)
                addLiveRoot(*it);
 
+       // if -exported_symbols_list that has wildcards, we need to find all matches and make them the roots 
+       // <rdar://problem/5524973>
+       if ( fOptions.hasWildCardExportRestrictList() ) {
+               for (std::vector<ObjectFile::Atom*>::iterator it=fAllAtoms.begin(); it != fAllAtoms.end(); it++) {
+                       ObjectFile::Atom* atom = *it;
+                       if ( (atom->getScope() == ObjectFile::Atom::scopeGlobal) 
+                               && (fDeadAtoms.count(atom) == 0) 
+                               && fOptions.shouldExport(atom->getName()) )
+                                       fLiveRootAtoms.insert(atom);
+               }
+       }
+
        // in some cases, every global scope atom in initial .o files is a root
        if ( fOptions.allGlobalsAreDeadStripRoots() ) {
                for (std::vector<ObjectFile::Atom*>::iterator it=fAllAtoms.begin(); it != fAllAtoms.end(); it++) {
@@ -1296,7 +1418,7 @@ void Linker::deadStripResolve()
                                        // by just adding this atom to fLiveAtoms set, we are assuming it has no
                                        // references, which is true for commons.
                                        if ( target->getDefinitionKind() != ObjectFile::Atom::kTentativeDefinition )
-                                               fprintf(stderr, "warning: ld64 internal error %s is not a tentative definition\n", target->getDisplayName());
+                                               warning("internal error %s is not a tentative definition", target->getDisplayName());
                                }
                        }
                        if ( reference->getFromTargetBinding() == ObjectFile::Reference::kUnboundByName ) {
@@ -1307,7 +1429,7 @@ void Linker::deadStripResolve()
                                        // by just adding this atom to fLiveAtoms set, we are assuming it has no
                                        // references, which is true for commons.
                                        if ( target->getDefinitionKind() != ObjectFile::Atom::kTentativeDefinition )
-                                               fprintf(stderr, "warning: ld64 internal error %s is not a tentative definition\n", target->getDisplayName());
+                                               warning("internal error %s is not a tentative definition", target->getDisplayName());
                                }
                        }
                }
@@ -1378,6 +1500,8 @@ static uint8_t pointerKind(cpu_type_t arch)
                        return x86::kPointer;
                case CPU_TYPE_X86_64:
                        return x86_64::kPointer;
+               case CPU_TYPE_ARM:
+                       return arm::kPointer;
        }
        throw "uknown architecture";
 }
@@ -1393,6 +1517,8 @@ static uint8_t pcRelKind(cpu_type_t arch)
                        return x86::kPointerDiff;
                case CPU_TYPE_X86_64:
                        return x86_64::kPointerDiff32;
+               case CPU_TYPE_ARM:
+                       return arm::kPointerDiff;
        }
        throw "uknown architecture";
 }
@@ -1412,31 +1538,37 @@ void Linker::processDTrace()
                ProviderToProbes providerToProbes;
                std::vector<DTraceProbeInfo> emptyList;
                for(std::vector<DTraceProbeInfo>::iterator it = fDtraceProbeSites.begin(); it != fDtraceProbeSites.end(); ++it) {
-                       const char* providerStart = &it->probeName[16];
-                       const char* providerEnd = strchr(providerStart, '$');
-                       if ( providerEnd != NULL ) {
-                               char providerName[providerEnd-providerStart+1];
-                               strlcpy(providerName, providerStart, providerEnd-providerStart+1);
-                               ProviderToProbes::iterator pos = providerToProbes.find(providerName);
-                               if ( pos == providerToProbes.end() ) {
-                                       const char* dup = strdup(providerName);
-                                       providerToProbes[dup] = emptyList;
+                       // ignore probes in functions that were coalesed away rdar://problem/5628149
+                       if ( fDeadAtoms.count((ObjectFile::Atom*)(it->atom)) == 0 ) {
+                               const char* providerStart = &it->probeName[16];
+                               const char* providerEnd = strchr(providerStart, '$');
+                               if ( providerEnd != NULL ) {
+                                       char providerName[providerEnd-providerStart+1];
+                                       strlcpy(providerName, providerStart, providerEnd-providerStart+1);
+                                       ProviderToProbes::iterator pos = providerToProbes.find(providerName);
+                                       if ( pos == providerToProbes.end() ) {
+                                               const char* dup = strdup(providerName);
+                                               providerToProbes[dup] = emptyList;
+                                       }
+                                       providerToProbes[providerName].push_back(*it);
                                }
-                               providerToProbes[providerName].push_back(*it);
                        }
                }
                for(std::vector<DTraceProbeInfo>::iterator it = fDtraceIsEnabledSites.begin(); it != fDtraceIsEnabledSites.end(); ++it) {
-                       const char* providerStart = &it->probeName[20];
-                       const char* providerEnd = strchr(providerStart, '$');
-                       if ( providerEnd != NULL ) {
-                               char providerName[providerEnd-providerStart+1];
-                               strlcpy(providerName, providerStart, providerEnd-providerStart+1);
-                               ProviderToProbes::iterator pos = providerToProbes.find(providerName);
-                               if ( pos == providerToProbes.end() ) {
-                                       const char* dup = strdup(providerName);
-                                       providerToProbes[dup] = emptyList;
+                       // ignore probes in functions that were coalesed away rdar://problem/5628149
+                       if ( fDeadAtoms.count((ObjectFile::Atom*)(it->atom)) == 0 ) {
+                               const char* providerStart = &it->probeName[20];
+                               const char* providerEnd = strchr(providerStart, '$');
+                               if ( providerEnd != NULL ) {
+                                       char providerName[providerEnd-providerStart+1];
+                                       strlcpy(providerName, providerStart, providerEnd-providerStart+1);
+                                       ProviderToProbes::iterator pos = providerToProbes.find(providerName);
+                                       if ( pos == providerToProbes.end() ) {
+                                               const char* dup = strdup(providerName);
+                                               providerToProbes[dup] = emptyList;
+                                       }
+                                       providerToProbes[providerName].push_back(*it);
                                }
-                               providerToProbes[providerName].push_back(*it);
                        }
                }
                
@@ -1450,10 +1582,10 @@ void Linker::processDTrace()
                        // open library and find dtrace_create_dof()
                        void* handle = dlopen("/usr/lib/libdtrace.dylib", RTLD_LAZY);
                        if ( handle == NULL )
-                               throwf("couldn't dlopen() /usr/lib/libdtrace.dylib: %s\n", dlerror());
+                               throwf("couldn't dlopen() /usr/lib/libdtrace.dylib: %s", dlerror());
                        createdof_func_t pCreateDOF = (createdof_func_t)dlsym(handle, "dtrace_ld_create_dof");
                        if ( pCreateDOF == NULL )
-                               throwf("couldn't find \"dtrace_ld_create_dof\" in /usr/lib/libdtrace.dylib: %s\n", dlerror());
+                               throwf("couldn't find \"dtrace_ld_create_dof\" in /usr/lib/libdtrace.dylib: %s", dlerror());
                        // build list of typedefs/stability infos for this provider
                        CStringSet types;
                        for(std::vector<DTraceProbeInfo>::const_iterator it = probes.begin(); it != probes.end(); ++it) {
@@ -1493,6 +1625,9 @@ void Linker::processDTrace()
                                offsetsInDOF[index] = 0;
                                ++index;
                        }
+                       //fprintf(stderr, "calling libtrace to create DOF\n");
+                       //for(uint32_t i=0; i < probeCount; ++i) 
+                       //      fprintf(stderr, "  [%u]\t %s\t%s\n", i, probeNames[i], funtionNames[i]);
                        // call dtrace library to create DOF section
                        size_t dofSectionSize;
                        uint8_t* p = (*pCreateDOF)(fArchitecture, typeCount, typeNames, probeCount, probeNames, funtionNames, offsetsInDOF, &dofSectionSize);
@@ -1561,7 +1696,7 @@ void Linker::processDTrace()
                        for (uint32_t i=0; i < probeCount; ++i) {
                                uint64_t offset = offsetsInDOF[i];
                                if ( offset > dofSectionSize )
-                                       throwf("offsetsInDOF[i]=%0llX > dofSectionSize=%0lX\n", i, offset, dofSectionSize);
+                                       throwf("offsetsInDOF[i]=%0llX > dofSectionSize=%0lX", i, offset, dofSectionSize);
                                reader->addSectionReference(pointerKind(fArchitecture), offset, fDtraceProbes[i].atom, fDtraceProbes[i].offset);
                        }
                        this->addAtoms(reader->getAtoms());
@@ -1676,8 +1811,8 @@ ObjectFile::Atom* Linker::findAtom(const Options::OrderedSymbol& orderedSymbol)
                                        if ( (name != NULL) && (strcmp(name, orderedSymbol.symbolName) == 0) ) {
                                                if ( matchesObjectFile(atom, orderedSymbol.objectFileName) ) {
                                                        if ( fOptions.printOrderFileStatistics() )
-                                                               fprintf(stderr, "ld: warning %s specified in order_file but it exists in multiple .o files. "
-                                                                               "Prefix symbol with .o filename in order_file to disambiguate\n", orderedSymbol.symbolName);
+                                                               warning("%s specified in order_file but it exists in multiple .o files. "
+                                                                               "Prefix symbol with .o filename in order_file to disambiguate", orderedSymbol.symbolName);
                                                        return atom;
                                                }
                                        }
@@ -1707,8 +1842,8 @@ ObjectFile::Atom* Linker::findAtom(const Options::OrderedSymbol& orderedSymbol)
                                                if ( strcmp(canonicalAtomName, canonicalName) == 0 ) {
                                                        if ( matchesObjectFile(atom, orderedSymbol.objectFileName) ) {
                                                                if ( fOptions.printOrderFileStatistics() )
-                                                                       fprintf(stderr, "ld: warning %s specified in order_file but it exists in multiple .o files. "
-                                                                               "Prefix symbol with .o filename in order_file to disambiguate\n", orderedSymbol.symbolName);
+                                                                       warning("%s specified in order_file but it exists in multiple .o files. "
+                                                                               "Prefix symbol with .o filename in order_file to disambiguate", orderedSymbol.symbolName);
                                                                return atom;
                                                        }
                                                }
@@ -1798,7 +1933,7 @@ void Linker::sortAtoms()
                                                // gerneral case of inserting into an existing cluster
                                                if ( followOnNexts[atom] != NULL ) {
                                                        // an atom with two follow-ons is illegal
-                                                       fprintf(stderr, "ld: warning can't order %s because both %s and %s must follow it\n",
+                                                       warning("can't order %s because both %s and %s must follow it",
                                                                                atom->getDisplayName(), targetAtom->getDisplayName(), followOnNexts[atom]->getDisplayName());
                                                }
                                                else {
@@ -1810,7 +1945,7 @@ void Linker::sortAtoms()
                                                        bool otherIsAlias = (originalPrevious->getSize() == 0);
                                                        bool thisIsAlias = (atom->getSize() == 0);
                                                        if ( !otherIsAlias && !thisIsAlias ) {
-                                                               fprintf(stderr, "ld: warning can't order %s because both %s and %s must preceed it\n",
+                                                               warning("can't order %s because both %s and %s must preceed it",
                                                                                        targetAtom->getDisplayName(), originalPrevious->getDisplayName(), atom->getDisplayName());
                                                        }
                                                        else if ( otherIsAlias ) {
@@ -1890,7 +2025,7 @@ void Linker::sortAtoms()
                         ++index;
                }
                if ( fOptions.printOrderFileStatistics() && (fOptions.orderedSymbols().size() != matchCount) ) {
-                       fprintf(stderr, "ld: warning only %u out of %lu order_file symbols were applicable\n", matchCount, fOptions.orderedSymbols().size() );
+                       warning("only %u out of %lu order_file symbols were applicable", matchCount, fOptions.orderedSymbols().size() );
                }
        }
 
@@ -1914,11 +2049,11 @@ void Linker::tweakLayout()
                if ( (fTotalSize-fTotalZeroFillSize) > 0x7F000000 )
                        throwf("total output size exceeds 2GB (%lldMB)", (fTotalSize-fTotalZeroFillSize)/(1024*1024));          
 
-               // move very large (>1MB) zero fill atoms to a new section at very end
+               // move very large (>1MB) zero fill atoms to a new section at very end of __DATA segment
                Section* hugeZeroFills = Section::find("__huge", "__DATA", true);
                for (std::vector<ObjectFile::Atom*>::iterator it=fAllAtoms.begin(); it != fAllAtoms.end(); it++) {
                        ObjectFile::Atom* atom = *it;
-                       if ( atom->isZeroFill() && (atom->getSize() > 1024*1024) && atom->getSegment().isContentReadable() )
+                       if ( atom->isZeroFill() && (atom->getSize() > 1024*1024) && (strcmp(atom->getSegment().getName(), "__DATA") == 0) )
                                atom->setSection(hugeZeroFills);
                }
        }
@@ -1999,12 +2134,12 @@ void Linker::writeDotOutput()
                        fclose(out);
                }
                else {
-                       fprintf(stderr, "ld: warning could not write dot output file: %s\n", dotOutFilePath);
+                       warning("could not write dot output file: %s", dotOutFilePath);
                }
        }
 }
 
-ObjectFile::Atom* Linker::entryPoint()
+ObjectFile::Atom* Linker::entryPoint(bool orInit)
 {
        // if main executable, find entry point atom
        ObjectFile::Atom* entryPoint = NULL;
@@ -2018,7 +2153,7 @@ ObjectFile::Atom* Linker::entryPoint()
                        }
                        break;
                case Options::kDynamicLibrary:
-                       if ( fOptions.initFunctionName() != NULL ) {
+                       if ( orInit && (fOptions.initFunctionName() != NULL) ) {
                                entryPoint = fGlobalSymbolTable.find(fOptions.initFunctionName());
                                if ( entryPoint == NULL ) {
                                        throwf("could not find -init function: \"%s\"", fOptions.initFunctionName());
@@ -2038,6 +2173,11 @@ ObjectFile::Atom* Linker::dyldHelper()
        return fGlobalSymbolTable.find("dyld_stub_binding_helper");
 }
 
+ObjectFile::Atom* Linker::dyldLazyLibraryHelper()
+{
+       return fGlobalSymbolTable.find("dyld_lazy_dylib_stub_binding_helper");
+}
+
 const char* Linker::assureFullPath(const char* path)
 {
        if ( path[0] == '/' )
@@ -2140,7 +2280,7 @@ static PathToSums sKnownBINCLs;
 
 void Linker::collectStabs(ObjectFile::Reader* reader, std::map<const class ObjectFile::Atom*, uint32_t>& atomOrdinals)
 {
-       bool log = false;
+       const bool log = false;
        bool minimal = ( fOptions.readerOptions().fDebugInfoStripping == ObjectFile::ReaderOptions::kDebugInfoMinimal );
        std::vector<class ObjectFile::Reader::Stab>* readerStabs = reader->getStabs();
        if ( readerStabs == NULL )
@@ -2177,7 +2317,7 @@ void Linker::collectStabs(ObjectFile::Reader* reader, std::map<const class Objec
                                break;
                        case N_EINCL:
                                if ( curRangeIndex == -1 ) {
-                                       fprintf(stderr, "ld: warning EINCL missing BINCL in %s\n", reader->getPath());
+                                       warning("EINCL missing BINCL in %s", reader->getPath());
                                }
                                else {
                                        ranges[curRangeIndex].end = it+1;
@@ -2211,7 +2351,7 @@ void Linker::collectStabs(ObjectFile::Reader* reader, std::map<const class Objec
                                if ( curRangeIndex != -1 ) {
                                        ranges[curRangeIndex].cannotEXCL = true;
                                        if ( fOptions.warnStabs() )
-                                               fprintf(stderr, "ld: cannot do BINCL/EINCL optimzation because of stabs kinds in %s for %s\n", ranges[curRangeIndex].begin->string, reader->getPath());
+                                               warning("cannot do BINCL/EINCL optimzation because of stabs kinds in %s for %s\n", ranges[curRangeIndex].begin->string, reader->getPath());
                                }
                                break;
                        case N_SO:
@@ -2249,24 +2389,26 @@ void Linker::collectStabs(ObjectFile::Reader* reader, std::map<const class Objec
        }
        if ( log ) fprintf(stderr, "processesed %d stabs for %s\n", count, reader->getPath());
        if ( curRangeIndex != -1 )
-               fprintf(stderr, "ld: warning BINCL (%s) missing EINCL in %s\n", ranges[curRangeIndex].begin->string, reader->getPath());
+               warning("BINCL (%s) missing EINCL in %s", ranges[curRangeIndex].begin->string, reader->getPath());
 
        // if no BINCLs
        if ( ranges.size() == 0 ) {
-               int soIndex = 0;
+               unsigned int soIndex = 0;
                for(std::vector<ObjectFile::Reader::Stab>::iterator it=readerStabs->begin(); it != readerStabs->end(); ++it) {
                        // copy minimal or all stabs
                        ObjectFile::Reader::Stab stab = *it;
                        if ( !minimal || minimizeStab(stab) ) {
                                if ( stab.type == N_SO ) {
-                                       if ( (stab.string != NULL) && (strlen(stab.string) > 0) ) {
-                                               // starting SO is associated with first atom
-                                               stab.atom = soRanges[soIndex].first;
-                                       }
-                                       else {
-                                               // ending SO is associated with last atom
-                                               stab.atom = soRanges[soIndex].second;
-                                               ++soIndex;
+                                       if ( soIndex < soRanges.size() ) {
+                                               if ( (stab.string != NULL) && (strlen(stab.string) > 0) ) {
+                                                       // starting SO is associated with first atom
+                                                       stab.atom = soRanges[soIndex].first;
+                                               }
+                                               else {
+                                                       // ending SO is associated with last atom
+                                                       stab.atom = soRanges[soIndex].second;
+                                                       ++soIndex;
+                                               }
                                        }
                                }
                                fStabs.push_back(stab);
@@ -2534,33 +2676,37 @@ void Linker::synthesizeDebugNotes(std::vector<class ObjectFile::Atom*>& allAtoms
                                endSym.string           = "";
                                fStabs.push_back(endSym);
                        }
+                       else if ( atom->getSymbolTableInclusion() == ObjectFile::Atom::kSymbolTableNotIn ) {
+                               // no stabs for atoms that would not be in the symbol table
+                       }
+                       else if ( atom->getSymbolTableInclusion() == ObjectFile::Atom::kSymbolTableInAsAbsolute ) {
+                               // no stabs for absolute symbols
+                       }
+                       else if ( (strcmp(atom->getSectionName(), "__eh_frame") == 0) ) {
+                               // no stabs for .eh atoms
+                       }
                        else {
                                ObjectFile::Reader::Stab globalsStab;
+                               const char* name = atom->getName();
                                if ( atom->getScope() == ObjectFile::Atom::scopeTranslationUnit ) {
                                        // Synthesize STSYM stab for statics
-                                       const char* name = atom->getName();
-                                       if ( name[0] == '_' ) {
-                                               globalsStab.atom                = atom;
-                                               globalsStab.type                = N_STSYM;
-                                               globalsStab.other               = 1;
-                                               globalsStab.desc                = 0;
-                                               globalsStab.value               = 0;
-                                               globalsStab.string              = name;
-                                               fStabs.push_back(globalsStab);
-                                       }
+                                       globalsStab.atom                = atom;
+                                       globalsStab.type                = N_STSYM;
+                                       globalsStab.other               = 1;
+                                       globalsStab.desc                = 0;
+                                       globalsStab.value               = 0;
+                                       globalsStab.string              = name;
+                                       fStabs.push_back(globalsStab);
                                }
                                else {
-                                       // Synthesize GSYM stab for other globals (but not .eh exception frame symbols)
-                                       const char* name = atom->getName();
-                                       if ( (name[0] == '_') && (strcmp(atom->getSectionName(), "__eh_frame") != 0) ) {
-                                               globalsStab.atom                = atom;
-                                               globalsStab.type                = N_GSYM;
-                                               globalsStab.other               = 1;
-                                               globalsStab.desc                = 0;
-                                               globalsStab.value               = 0;
-                                               globalsStab.string              = name;
-                                               fStabs.push_back(globalsStab);
-                                       }
+                                       // Synthesize GSYM stab for other globals
+                                       globalsStab.atom                = atom;
+                                       globalsStab.type                = N_GSYM;
+                                       globalsStab.other               = 1;
+                                       globalsStab.desc                = 0;
+                                       globalsStab.value               = 0;
+                                       globalsStab.string              = name;
+                                       fStabs.push_back(globalsStab);
                                }
                        }
                }
@@ -2686,12 +2832,14 @@ void Linker::writeOutput()
 {
        if ( fOptions.forceCpuSubtypeAll() )
                fCurrentCpuConstraint = ObjectFile::Reader::kCpuAny;
-               
+
        fStartWriteTime = mach_absolute_time();
        // tell writer about each segment's atoms
-       fOutputFileSize = fOutputFile->write(fAllAtoms, fStabs, this->entryPoint(), this->dyldHelper(),
+       fOutputFileSize = fOutputFile->write(fAllAtoms, fStabs, this->entryPoint(true), 
+                                                                                       this->dyldHelper(), this->dyldLazyLibraryHelper(),
                                                                                        fCreateUUID, fCanScatter, 
-                                                                                       fCurrentCpuConstraint, fBiggerThanTwoGigOutput);
+                                                                                       fCurrentCpuConstraint, fBiggerThanTwoGigOutput, 
+                                                                                       fGlobalSymbolTable.hasExternalWeakDefinitions());
 }
 
 ObjectFile::Reader* Linker::createReader(const Options::FileInfo& info)
@@ -2709,27 +2857,47 @@ ObjectFile::Reader* Linker::createReader(const Options::FileInfo& info)
                throwf("can't map file, errno=%d", errno);
 
        // if fat file, skip to architecture we want
+       // Note: fat header is always big-endian
        const fat_header* fh = (fat_header*)p;
        if ( fh->magic == OSSwapBigToHostInt32(FAT_MAGIC) ) {
-               // Fat header is always big-endian
                const struct fat_arch* archs = (struct fat_arch*)(p + sizeof(struct fat_header));
-               for (unsigned long i=0; i < OSSwapBigToHostInt32(fh->nfat_arch); ++i) {
-                       if ( OSSwapBigToHostInt32(archs[i].cputype) == (uint32_t)fArchitecture ) {
-                               uint32_t fileOffset = OSSwapBigToHostInt32(archs[i].offset);
-                               len = OSSwapBigToHostInt32(archs[i].size);
-                               // if requested architecture is page aligned within fat file, then remap just that portion of file
-                               if ( (fileOffset & 0x00000FFF) == 0 ) {
-                                       // unmap whole file
-                                       munmap((caddr_t)p, info.fileLen);
-                                       // re-map just part we need
-                                       p = (uint8_t*)::mmap(NULL, len, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, fileOffset);
-                                       if ( p == (uint8_t*)(-1) )
-                                               throwf("can't re-map file, errno=%d", errno);
+               uint32_t sliceToUse;
+               bool sliceFound = false;
+               if ( fOptions.preferSubArchitecture() ) {
+                       // first try to find a slice that match cpu-type and cpu-sub-type
+                       for (uint32_t i=0; i < OSSwapBigToHostInt32(fh->nfat_arch); ++i) {
+                               if ( (OSSwapBigToHostInt32(archs[i].cputype) == (uint32_t)fArchitecture)
+                                 && (OSSwapBigToHostInt32(archs[i].cpusubtype) == (uint32_t)fOptions.subArchitecture()) ) {
+                                       sliceToUse = i;
+                                       sliceFound = true;
+                                       break;
                                }
-                               else {
-                                       p = &p[fileOffset];
+                       }
+               }
+               if ( !sliceFound ) {
+                       // look for any slice that matches just cpu-type
+                       for (uint32_t i=0; i < OSSwapBigToHostInt32(fh->nfat_arch); ++i) {
+                               if ( OSSwapBigToHostInt32(archs[i].cputype) == (uint32_t)fArchitecture ) {
+                                       sliceToUse = i;
+                                       sliceFound = true;
+                                       break;
                                }
-                               break;
+                       }
+               }
+               if ( sliceFound ) {
+                       uint32_t fileOffset = OSSwapBigToHostInt32(archs[sliceToUse].offset);
+                       len = OSSwapBigToHostInt32(archs[sliceToUse].size);
+                       // if requested architecture is page aligned within fat file, then remap just that portion of file
+                       if ( (fileOffset & 0x00000FFF) == 0 ) {
+                               // unmap whole file
+                               munmap((caddr_t)p, info.fileLen);
+                               // re-map just part we need
+                               p = (uint8_t*)::mmap(NULL, len, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, fileOffset);
+                               if ( p == (uint8_t*)(-1) )
+                                       throwf("can't re-map file, errno=%d", errno);
+                       }
+                       else {
+                               p = &p[fileOffset];
                        }
                }
        }
@@ -2740,39 +2908,50 @@ ObjectFile::Reader* Linker::createReader(const Options::FileInfo& info)
                        if ( mach_o::relocatable::Reader<ppc>::validFile(p) )
                                return this->addObject(new mach_o::relocatable::Reader<ppc>::Reader(p, info.path, info.modTime, fOptions.readerOptions(), fNextInputOrdinal), info, len);
                        else if ( mach_o::dylib::Reader<ppc>::validFile(p, info.options.fBundleLoader) )
-                               return this->addDylib(new mach_o::dylib::Reader<ppc>::Reader(p, len, info.path, info.options.fBundleLoader, fOptions.readerOptions(), fNextInputOrdinal), info, len);
-                       else if ( mach_o::archive::Reader<ppc>::validFile(p, len) )
-                               return this->addArchive(new mach_o::archive::Reader<ppc>::Reader(p, len, info.path, info.modTime, fOptions.readerOptions(), fNextInputOrdinal), info, len);
+                               return this->addDylib(new mach_o::dylib::Reader<ppc>::Reader(p, len, info.path, info.options, fOptions.readerOptions(), fNextInputOrdinal), info, len);
+                       else if ( archive::Reader<ppc>::validFile(p, len) )
+                               return this->addArchive(new archive::Reader<ppc>::Reader(p, len, info.path, info.modTime, fOptions.readerOptions(), fNextInputOrdinal), info, len);
                        break;
                case CPU_TYPE_POWERPC64:
                        if ( mach_o::relocatable::Reader<ppc64>::validFile(p) )
                                return this->addObject(new mach_o::relocatable::Reader<ppc64>::Reader(p, info.path, info.modTime, fOptions.readerOptions(), fNextInputOrdinal), info, len);
                        else if ( mach_o::dylib::Reader<ppc64>::validFile(p, info.options.fBundleLoader) )
-                               return this->addDylib(new mach_o::dylib::Reader<ppc64>::Reader(p, len, info.path, info.options.fBundleLoader, fOptions.readerOptions(), fNextInputOrdinal), info, len);
-                       else if ( mach_o::archive::Reader<ppc64>::validFile(p, len) )
-                               return this->addArchive(new mach_o::archive::Reader<ppc64>::Reader(p, len, info.path, info.modTime, fOptions.readerOptions(), fNextInputOrdinal), info, len);
+                               return this->addDylib(new mach_o::dylib::Reader<ppc64>::Reader(p, len, info.path, info.options, fOptions.readerOptions(), fNextInputOrdinal), info, len);
+                       else if ( archive::Reader<ppc64>::validFile(p, len) )
+                               return this->addArchive(new archive::Reader<ppc64>::Reader(p, len, info.path, info.modTime, fOptions.readerOptions(), fNextInputOrdinal), info, len);
                        break;
                case CPU_TYPE_I386:
                        if ( mach_o::relocatable::Reader<x86>::validFile(p) )
                                return this->addObject(new mach_o::relocatable::Reader<x86>::Reader(p, info.path, info.modTime, fOptions.readerOptions(), fNextInputOrdinal), info, len);
                        else if ( mach_o::dylib::Reader<x86>::validFile(p, info.options.fBundleLoader) )
-                               return this->addDylib(new mach_o::dylib::Reader<x86>::Reader(p, len, info.path, info.options.fBundleLoader, fOptions.readerOptions(), fNextInputOrdinal), info, len);
-                       else if ( mach_o::archive::Reader<x86>::validFile(p, len) )
-                               return this->addArchive(new mach_o::archive::Reader<x86>::Reader(p, len, info.path, info.modTime, fOptions.readerOptions(), fNextInputOrdinal), info, len);
+                               return this->addDylib(new mach_o::dylib::Reader<x86>::Reader(p, len, info.path, info.options, fOptions.readerOptions(), fNextInputOrdinal), info, len);
+                       else if ( archive::Reader<x86>::validFile(p, len) )
+                               return this->addArchive(new archive::Reader<x86>::Reader(p, len, info.path, info.modTime, fOptions.readerOptions(), fNextInputOrdinal), info, len);
                        break;
                case CPU_TYPE_X86_64:
                        if ( mach_o::relocatable::Reader<x86_64>::validFile(p) )
                                return this->addObject(new mach_o::relocatable::Reader<x86_64>::Reader(p, info.path, info.modTime, fOptions.readerOptions(), fNextInputOrdinal), info, len);
                        else if ( mach_o::dylib::Reader<x86_64>::validFile(p, info.options.fBundleLoader) )
-                               return this->addDylib(new mach_o::dylib::Reader<x86_64>::Reader(p, len, info.path, info.options.fBundleLoader, fOptions.readerOptions(), fNextInputOrdinal), info, len);
-                       else if ( mach_o::archive::Reader<x86_64>::validFile(p, len) )
-                               return this->addArchive(new mach_o::archive::Reader<x86_64>::Reader(p, len, info.path, info.modTime, fOptions.readerOptions(), fNextInputOrdinal), info, len);
+                               return this->addDylib(new mach_o::dylib::Reader<x86_64>::Reader(p, len, info.path, info.options, fOptions.readerOptions(), fNextInputOrdinal), info, len);
+                       else if ( archive::Reader<x86_64>::validFile(p, len) )
+                               return this->addArchive(new archive::Reader<x86_64>::Reader(p, len, info.path, info.modTime, fOptions.readerOptions(), fNextInputOrdinal), info, len);
+               case CPU_TYPE_ARM:
+                       if ( mach_o::relocatable::Reader<arm>::validFile(p) )
+                               return this->addObject(new mach_o::relocatable::Reader<arm>::Reader(p, info.path, info.modTime, fOptions.readerOptions(), fNextInputOrdinal), info, len);
+                       else if ( mach_o::dylib::Reader<arm>::validFile(p, info.options.fBundleLoader) )
+                               return this->addDylib(new mach_o::dylib::Reader<arm>::Reader(p, len, info.path, info.options, fOptions.readerOptions(), fNextInputOrdinal), info, len);
+                       else if ( archive::Reader<arm>::validFile(p, len) )
+                               return this->addArchive(new archive::Reader<arm>::Reader(p, len, info.path, info.modTime, fOptions.readerOptions(), fNextInputOrdinal), info, len);
+                       break;
                        break;
        }
 
-#if LLVM_SUPPORT
-       if ( LLVMReader::validFile(p, info.path, fArchitecture, fOptions) ) {
-               return this->addObject(LLVMReader::make(p, info.path, info.modTime, fOptions), info, len);
+#if LTO_SUPPORT
+       if ( lto::Reader::validFile(p, len, fArchitecture) ) {
+               return this->addObject(new lto::Reader(p, len, info.path, info.modTime, fOptions.readerOptions(), fArchitecture), info, len);
+       }
+       else if ( !lto::Reader::loaded() && (p[0] == 'B') && (p[1] == 'C')  ) {
+               throw "could not process object file.  Looks like an llvm bitcode object file, but libLTO.dylib could not be loaded";
        }
 #endif
        // error handling
@@ -2819,7 +2998,7 @@ ObjectFile::Reader* Linker::findDylib(const char* installPath, const char* fromP
                                        return reader;
                                }
                                catch (const char* msg) {
-                                       fprintf(stderr, "ld: warning ignoring -dylib_file option, %s\n", msg);
+                                       warning("ignoring -dylib_file option, %s", msg);
                                }
                        }
                }
@@ -2921,7 +3100,7 @@ void Linker::createReaders()
                                                // ignore, because this is about an architecture not in use
                                        }
                                        else {
-                                               fprintf(stderr, "ld: warning in %s, %s\n", entry.path, msg);
+                                               warning("in %s, %s", entry.path, msg);
                                        }
                                }
                                else {
@@ -3060,7 +3239,7 @@ ObjectFile::Reader* Linker::addDylib(ObjectFile::Reader* reader, const Options::
                        if ( pos2 == fDylibMap.end() ) 
                                fDylibMap[strdup(reader->getPath())] = reader;
                        else
-                               fprintf(stderr, "ld: warning, duplicate dylib %s\n", reader->getPath());
+                               warning("duplicate dylib %s", reader->getPath());
                }
        }
        else if ( info.options.fBundleLoader )
@@ -3090,7 +3269,7 @@ void Linker::logTraceInfo (const char* format, ...)
                if(trace_file_path != NULL) {
                        trace_file = open(trace_file_path, O_WRONLY | O_APPEND | O_CREAT, 0666);
                        if(trace_file == -1)
-                               throwf("Could not open or create trace file: %s\n", trace_file_path);
+                               throwf("Could not open or create trace file: %s", trace_file_path);
                }
                else {
                        trace_file = fileno(stderr);
@@ -3184,6 +3363,9 @@ void Linker::createWriter()
                case CPU_TYPE_X86_64:
                        this->setOutputFile(new mach_o::executable::Writer<x86_64>(path, fOptions, dynamicLibraries));
                        break;
+               case CPU_TYPE_ARM:
+                       this->setOutputFile(new mach_o::executable::Writer<arm>(path, fOptions, dynamicLibraries));
+                       break;
                default:
                        throw "unknown architecture";
        }
@@ -3191,7 +3373,7 @@ void Linker::createWriter()
 
 
 Linker::SymbolTable::SymbolTable(Linker& owner)
- : fOwner(owner), fRequireCount(0)
+ : fOwner(owner), fRequireCount(0), fHasExternalTentativeDefinitions(false), fHasExternalWeakDefinitions(false)
 {
 }
 
@@ -3248,7 +3430,20 @@ enum AllDefinitionCombinations {
 bool Linker::SymbolTable::add(ObjectFile::Atom& newAtom)
 {
        bool useNew = true;
+       bool checkVisibilityMismatch = false;
        const char* name = newAtom.getName();
+       if ( newAtom.getScope() == ObjectFile::Atom::scopeGlobal ) {
+               switch ( newAtom.getDefinitionKind() ) {
+                       case ObjectFile::Atom::kTentativeDefinition:
+                               fHasExternalTentativeDefinitions = true;
+                               break;
+                       case ObjectFile::Atom::kWeakDefinition:
+                               fHasExternalWeakDefinitions = true;
+                               break;
+                       default:
+                               break;
+               }
+       }
        //fprintf(stderr, "map.add(%s => %p from %s)\n", name, &newAtom, newAtom.getFile()->getPath());
        Mapper::iterator pos = fTable.find(name);
        ObjectFile::Atom* existingAtom = NULL;
@@ -3258,7 +3453,7 @@ bool Linker::SymbolTable::add(ObjectFile::Atom& newAtom)
                // already have atom with same name in symbol table
                switch ( (AllDefinitionCombinations)((existingAtom->getDefinitionKind() << 3) | newAtom.getDefinitionKind()) ) {
                        case kRegAndReg:
-                               throwf("duplicate symbol %s in %s and %s\n", name, newAtom.getFile()->getPath(), existingAtom->getFile()->getPath());
+                               throwf("duplicate symbol %s in %s and %s", name, newAtom.getFile()->getPath(), existingAtom->getFile()->getPath());
                        case kRegAndWeak:
                                // ignore new weak atom, because we already have a non-weak one
                                useNew = false;
@@ -3266,9 +3461,10 @@ bool Linker::SymbolTable::add(ObjectFile::Atom& newAtom)
                        case kRegAndTent:
                                // ignore new tentative atom, because we already have a regular one
                                useNew = false;
+                               checkVisibilityMismatch = true;
                                if ( newAtom.getSize() > existingAtom->getSize() ) {
-                                       fprintf(stderr, "ld: warning for symbol %s tentative definition of size %llu from %s is "
-                                                                       "is smaller than the real definition of size %llu from %s\n",
+                                       warning("for symbol %s tentative definition of size %llu from %s is "
+                                                                       "is smaller than the real definition of size %llu from %s",
                                                                        newAtom.getDisplayName(), newAtom.getSize(), newAtom.getFile()->getPath(),
                                                                        existingAtom->getSize(), existingAtom->getFile()->getPath());
                                }
@@ -3282,7 +3478,7 @@ bool Linker::SymbolTable::add(ObjectFile::Atom& newAtom)
                                useNew = false;
                                break;
                        case kRegAndAbsolute:
-                               throwf("duplicate symbol %s in %s and %s\n", name, newAtom.getFile()->getPath(), existingAtom->getFile()->getPath());
+                               throwf("duplicate symbol %s in %s and %s", name, newAtom.getFile()->getPath(), existingAtom->getFile()->getPath());
                                break;
                        case kWeakAndReg:
                                // replace existing weak atom with regular one
@@ -3291,6 +3487,7 @@ bool Linker::SymbolTable::add(ObjectFile::Atom& newAtom)
                                // have another weak atom, use whichever has largest alignment requirement
                                // because codegen of some client may require alignment
                                useNew = ( newAtom.getAlignment().trailingZeros() > existingAtom->getAlignment().trailingZeros() );
+                               checkVisibilityMismatch = true;
                                break;
                        case kWeakAndTent:
                                // replace existing weak atom with tentative one ???
@@ -3308,9 +3505,10 @@ bool Linker::SymbolTable::add(ObjectFile::Atom& newAtom)
                                break;
                        case kTentAndReg:
                                // replace existing tentative atom with regular one
+                               checkVisibilityMismatch = true;
                                if ( newAtom.getSize() < existingAtom->getSize() ) {
-                                       fprintf(stderr, "ld: warning for symbol %s tentative definition of size %llu from %s is "
-                                                                       "being replaced by a real definition of size %llu from %s\n",
+                                       warning("for symbol %s tentative definition of size %llu from %s is "
+                                                                       "being replaced by a real definition of size %llu from %s",
                                                                        newAtom.getDisplayName(), existingAtom->getSize(), existingAtom->getFile()->getPath(),
                                                                        newAtom.getSize(), newAtom.getFile()->getPath());
                                }
@@ -3320,12 +3518,13 @@ bool Linker::SymbolTable::add(ObjectFile::Atom& newAtom)
                                break;
                        case kTentAndTent:
                                // use largest
+                               checkVisibilityMismatch = true;
                                if ( newAtom.getSize() < existingAtom->getSize() ) {
                                        useNew = false;
                                } 
                                else {
                                        if ( newAtom.getAlignment().trailingZeros() < existingAtom->getAlignment().trailingZeros() )
-                                               fprintf(stderr, "ld: warning alignment lost in merging tentative definition %s\n", newAtom.getDisplayName());
+                                               warning("alignment lost in merging tentative definition %s", newAtom.getDisplayName());
                                }
                                break;
                        case kTentAndExtern:
@@ -3334,13 +3533,13 @@ bool Linker::SymbolTable::add(ObjectFile::Atom& newAtom)
                                switch ( fOwner.fOptions.commonsMode() ) {
                                        case Options::kCommonsIgnoreDylibs:
                                                if ( fOwner.fOptions.warnCommons() )
-                                                       fprintf(stderr, "ld: using common symbol %s from %s and ignoring defintion from dylib %s\n",
+                                                       warning("using common symbol %s from %s and ignoring defintion from dylib %s",
                                                                        existingAtom->getName(), existingAtom->getFile()->getPath(), newAtom.getFile()->getPath());
                                                useNew = false;
                                                break;
                                        case Options::kCommonsOverriddenByDylibs:
                                                if ( fOwner.fOptions.warnCommons() )
-                                                       fprintf(stderr, "ld: replacing common symbol %s from %s with true definition from dylib %s\n",
+                                                       warning("replacing common symbol %s from %s with true definition from dylib %s",
                                                                        existingAtom->getName(), existingAtom->getFile()->getPath(), newAtom.getFile()->getPath());
                                                break;
                                        case Options::kCommonsConflictsDylibsError:
@@ -3362,12 +3561,12 @@ bool Linker::SymbolTable::add(ObjectFile::Atom& newAtom)
                                switch ( fOwner.fOptions.commonsMode() ) {
                                        case Options::kCommonsIgnoreDylibs:
                                                if ( fOwner.fOptions.warnCommons() )
-                                                       fprintf(stderr, "ld: using common symbol %s from %s and ignoring defintion from dylib %s\n",
+                                                       warning("using common symbol %s from %s and ignoring defintion from dylib %s",
                                                                        newAtom.getName(), newAtom.getFile()->getPath(), existingAtom->getFile()->getPath());
                                                break;
                                        case Options::kCommonsOverriddenByDylibs:
                                                if ( fOwner.fOptions.warnCommons() )
-                                                       fprintf(stderr, "ld: replacing defintion of %s from dylib %s with common symbol from %s\n",
+                                                       warning("replacing defintion of %s from dylib %s with common symbol from %s",
                                                                        newAtom.getName(), existingAtom->getFile()->getPath(), newAtom.getFile()->getPath());
                                                useNew = false;
                                                break;
@@ -3396,12 +3595,12 @@ bool Linker::SymbolTable::add(ObjectFile::Atom& newAtom)
                                switch ( fOwner.fOptions.commonsMode() ) {
                                        case Options::kCommonsIgnoreDylibs:
                                                if ( fOwner.fOptions.warnCommons() )
-                                                       fprintf(stderr, "ld: using common symbol %s from %s and ignoring defintion from dylib %s\n",
+                                                       warning("using common symbol %s from %s and ignoring defintion from dylib %s",
                                                                        newAtom.getName(), newAtom.getFile()->getPath(), existingAtom->getFile()->getPath());
                                                break;
                                        case Options::kCommonsOverriddenByDylibs:
                                                if ( fOwner.fOptions.warnCommons() )
-                                                       fprintf(stderr, "ld: replacing defintion of %s from dylib %s with common symbol from %s\n",
+                                                       warning("replacing defintion of %s from dylib %s with common symbol from %s",
                                                                        newAtom.getName(), existingAtom->getFile()->getPath(), newAtom.getFile()->getPath());
                                                useNew = false;
                                                break;
@@ -3421,7 +3620,7 @@ bool Linker::SymbolTable::add(ObjectFile::Atom& newAtom)
                                // replace existing weak external with absolute
                                break;
                        case kAbsoluteAndReg:
-                               throwf("duplicate symbol %s in %s and %s\n", name, newAtom.getFile()->getPath(), existingAtom->getFile()->getPath());
+                               throwf("duplicate symbol %s in %s and %s", name, newAtom.getFile()->getPath(), existingAtom->getFile()->getPath());
                        case kAbsoluteAndWeak:
                                // ignore new weak atom, because we already have a non-weak one
                                useNew = false;
@@ -3439,21 +3638,21 @@ bool Linker::SymbolTable::add(ObjectFile::Atom& newAtom)
                                useNew = false;
                                break;
                        case kAbsoluteAndAbsolute:
-                               throwf("duplicate symbol %s in %s and %s\n", name, newAtom.getFile()->getPath(), existingAtom->getFile()->getPath());
+                               throwf("duplicate symbol %s in %s and %s", name, newAtom.getFile()->getPath(), existingAtom->getFile()->getPath());
                                break;
                }
        }
-       if ( (existingAtom != NULL) && (newAtom.getScope() != existingAtom->getScope()) ) {
-               fprintf(stderr, "ld: warning %s has different visibility (%d) in %s and (%d) in %s\n", 
-                       newAtom.getDisplayName(), newAtom.getScope(), newAtom.getFile()->getPath(), existingAtom->getScope(), existingAtom->getFile()->getPath());
+       if ( (existingAtom != NULL) && checkVisibilityMismatch && (newAtom.getScope() != existingAtom->getScope()) ) {
+               warning("%s has different visibility (%s) in %s and (%s) in %s", 
+                       newAtom.getDisplayName(), (newAtom.getScope() == 1 ? "hidden" : "default"), newAtom.getFile()->getPath(), (existingAtom->getScope()  == 1 ? "hidden" : "default"), existingAtom->getFile()->getPath());
        }
        if ( useNew ) {
                fTable[name] = &newAtom;
                if ( existingAtom != NULL )
-                       fOwner.fDeadAtoms.insert(existingAtom);
+                       fOwner.markDead(existingAtom);
        }
        else {
-               fOwner.fDeadAtoms.insert(&newAtom);
+               fOwner.markDead(&newAtom);
        }
        return useNew;
 }
@@ -3481,7 +3680,6 @@ void Linker::SymbolTable::getNeededNames(bool andWeakDefintions, std::vector<con
 
 
 
-
 bool Linker::AtomSorter::operator()(const ObjectFile::Atom* left, const ObjectFile::Atom* right)
 {
        if ( left == right )
@@ -3519,7 +3717,7 @@ bool Linker::AtomSorter::operator()(const ObjectFile::Atom* left, const ObjectFi
                        }
                }
        }
-       
+
        // the __common section can have real or tentative definitions
        // we want the real ones to sort before tentative ones
        bool leftIsTent  =  (left->getDefinitionKind() == ObjectFile::Atom::kTentativeDefinition);
old mode 100644 (file)
new mode 100755 (executable)
index 7f0e134..b4ccd34
 #include <stdio.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <mach-o/loader.h>
-#include <mach-o/fat.h>
-#include <mach-o/stab.h>
-#include <mach-o/reloc.h>
-#include <mach-o/ppc/reloc.h>
-#include <mach-o/x86_64/reloc.h>
 
 #include <vector>
 #include <set>
@@ -187,12 +181,29 @@ bool MachOChecker<x86_64>::validFile(const uint8_t* fileContent)
        return false;
 }
 
+template <>
+bool MachOChecker<arm>::validFile(const uint8_t* fileContent)
+{      
+       const macho_header<P>* header = (const macho_header<P>*)fileContent;
+       if ( header->magic() != MH_MAGIC )
+               return false;
+       if ( header->cputype() != CPU_TYPE_ARM )
+               return false;
+       switch (header->filetype()) {
+               case MH_EXECUTE:
+               case MH_DYLIB:
+               case MH_BUNDLE:
+               case MH_DYLINKER:
+                       return true;
+       }
+       return false;
+}
 
 template <> uint8_t MachOChecker<ppc>::loadCommandSizeMask()   { return 0x03; }
 template <> uint8_t MachOChecker<ppc64>::loadCommandSizeMask() { return 0x07; }
 template <> uint8_t MachOChecker<x86>::loadCommandSizeMask()   { return 0x03; }
 template <> uint8_t MachOChecker<x86_64>::loadCommandSizeMask() { return 0x07; }
-
+template <> uint8_t MachOChecker<arm>::loadCommandSizeMask()   { return 0x03; }
 
 template <typename A>
 MachOChecker<A>::MachOChecker(const uint8_t* fileContent, uint32_t fileLength, const char* path)
@@ -239,6 +250,7 @@ template <typename A>
 void MachOChecker<A>::checkLoadCommands()
 {
        // check that all load commands fit within the load command space file
+       const macho_encryption_info_command<P>* encryption_info = NULL;
        const uint8_t* const endOfFile = (uint8_t*)fHeader + fLength;
        const uint8_t* const endOfLoadCommands = (uint8_t*)fHeader + sizeof(macho_header<P>) + fHeader->sizeofcmds();
        const uint32_t cmd_count = fHeader->ncmds();
@@ -268,9 +280,14 @@ void MachOChecker<A>::checkLoadCommands()
                        case LC_TWOLEVEL_HINTS:
                        case LC_PREBIND_CKSUM:
                        case LC_LOAD_WEAK_DYLIB:
+                       case LC_LAZY_LOAD_DYLIB:
                        case LC_UUID:
                        case LC_REEXPORT_DYLIB:
                        case LC_SEGMENT_SPLIT_INFO:
+                       case LC_CODE_SIGNATURE:
+                               break;
+                       case LC_ENCRYPTION_INFO:
+                               encryption_info = (macho_encryption_info_command<P>*)cmd;
                                break;
                        case LC_SUB_UMBRELLA:
                        case LC_SUB_LIBRARY:
@@ -360,7 +377,7 @@ void MachOChecker<A>::checkLoadCommands()
                                        throwf("section %s vm address not within segment", sect->sectname());
                                if ( (sect->addr()+sect->size()) > endAddr )
                                        throwf("section %s vm address not within segment", sect->sectname());
-                               if ( ((sect->flags() &SECTION_TYPE) != S_ZEROFILL) && (segCmd->filesize() != 0) ) {
+                               if ( ((sect->flags() & SECTION_TYPE) != S_ZEROFILL) && (segCmd->filesize() != 0) ) {
                                        if ( sect->offset() < startOffset )
                                                throwf("section %s file offset not within segment", sect->sectname());
                                        if ( (sect->offset()+sect->size()) > endOffset )
@@ -396,6 +413,25 @@ void MachOChecker<A>::checkLoadCommands()
                }
        }
 
+       // verify encryption info
+       if ( encryption_info != NULL ) {
+               if ( fHeader->filetype() != MH_EXECUTE )
+                       throw "LC_ENCRYPTION_INFO load command is only legal in main executables";
+               if ( encryption_info->cryptoff() <  (sizeof(macho_header<P>) + fHeader->sizeofcmds()) )
+                       throw "LC_ENCRYPTION_INFO load command has cryptoff covers some load commands";
+               if ( (encryption_info->cryptoff() % 4096) != 0 )
+                       throw "LC_ENCRYPTION_INFO load command has cryptoff which is not page aligned";
+               if ( (encryption_info->cryptsize() % 4096) != 0 )
+                       throw "LC_ENCRYPTION_INFO load command has cryptsize which is not page sized";
+               for (typename std::vector<std::pair<pint_t, pint_t> >::iterator it = segmentFileOffsetRanges.begin(); 
+                                                                                                                               it != segmentFileOffsetRanges.end(); ++it) {
+                       if ( (it->first <= encryption_info->cryptoff()) && (encryption_info->cryptoff() < it->second) ) {
+                               if ( (encryption_info->cryptoff() + encryption_info->cryptsize()) > it->second )
+                                       throw "LC_ENCRYPTION_INFO load command is not contained within one segment";
+                       }
+               }
+       }
+
        // check LC_SYMTAB, LC_DYSYMTAB, and LC_SEGMENT_SPLIT_INFO
        cmd = cmds;
        bool foundDynamicSymTab = false;
@@ -591,6 +627,15 @@ x86_64::P::uint_t MachOChecker<x86_64>::relocBase()
        return fFirstWritableSegment->vmaddr();
 }
 
+template <>
+arm::P::uint_t MachOChecker<arm>::relocBase()
+{
+       if ( fHeader->flags() & MH_SPLIT_SEGS )
+               return fFirstWritableSegment->vmaddr();
+       else
+               return fFirstSegment->vmaddr();
+}
+
 
 template <typename A>
 bool MachOChecker<A>::addressInWritableSegment(pint_t address)
@@ -601,9 +646,19 @@ bool MachOChecker<A>::addressInWritableSegment(pint_t address)
        for (uint32_t i = 0; i < cmd_count; ++i) {
                if ( cmd->cmd() == macho_segment_command<P>::CMD ) {
                        const macho_segment_command<P>* segCmd = (const macho_segment_command<P>*)cmd;
-                       if ( (segCmd->initprot() & VM_PROT_WRITE) != 0 ) {
-                               if ( (address >= segCmd->vmaddr()) && (address < segCmd->vmaddr()+segCmd->vmsize()) )
+                       if ( (address >= segCmd->vmaddr()) && (address < segCmd->vmaddr()+segCmd->vmsize()) ) {
+                               // if segment is writable, we are fine
+                               if ( (segCmd->initprot() & VM_PROT_WRITE) != 0 ) 
                                        return true;
+                               // could be a text reloc, make sure section bit is set
+                               const macho_section<P>* const sectionsStart = (macho_section<P>*)((char*)segCmd + sizeof(macho_segment_command<P>));
+                               const macho_section<P>* const sectionsEnd = &sectionsStart[segCmd->nsects()];
+                               for(const macho_section<P>* sect = sectionsStart; sect < sectionsEnd; ++sect) {
+                                       if ( (sect->addr() <= address) && (address < (sect->addr()+sect->size())) ) {
+                                               // found section for this address, if has relocs we are fine
+                                               return ( (sect->flags() & (S_ATTR_EXT_RELOC|S_ATTR_LOC_RELOC)) != 0 );
+                                       }
+                               }
                        }
                }
                cmd = (const macho_load_command<P>*)(((uint8_t*)cmd)+cmd->cmdsize());
@@ -677,6 +732,23 @@ void MachOChecker<x86_64>::checkExternalReloation(const macho_relocation_info<P>
        // FIX: check r_symbol
 }
 
+template <>
+void MachOChecker<arm>::checkExternalReloation(const macho_relocation_info<P>* reloc)
+{
+       if ( reloc->r_length() != 2 ) 
+               throw "bad external relocation length";
+       if ( reloc->r_type() != ARM_RELOC_VANILLA ) 
+               throw "unknown external relocation type";
+       if ( reloc->r_pcrel() != 0 ) 
+               throw "bad external relocation pc_rel";
+       if ( reloc->r_extern() == 0 )
+               throw "local relocation found with external relocations";
+       if ( ! this->addressInWritableSegment(reloc->r_address() + this->relocBase()) )
+               throw "external relocation address not in writable segment";
+       // FIX: check r_symbol
+}
+
+
 template <>
 void MachOChecker<ppc>::checkLocalReloation(const macho_relocation_info<P>* reloc)
 {
@@ -687,9 +759,12 @@ void MachOChecker<ppc>::checkLocalReloation(const macho_relocation_info<P>* relo
        
        }
        else {
+               // ignore pair relocs
+               if ( reloc->r_type() == PPC_RELOC_PAIR ) 
+                       return;
                // FIX
                if ( ! this->addressInWritableSegment(reloc->r_address() + this->relocBase()) )
-                       throw "local relocation address not in writable segment";
+                       throwf("local relocation address 0x%08X not in writable segment", reloc->r_address());
        }
 }
 
@@ -730,7 +805,26 @@ void MachOChecker<x86_64>::checkLocalReloation(const macho_relocation_info<P>* r
                throw "local relocation address not in writable segment";
 }
 
-
+template <>
+void MachOChecker<arm>::checkLocalReloation(const macho_relocation_info<P>* reloc)
+{
+       if ( reloc->r_address() & R_SCATTERED ) {
+               // scattered
+               const macho_scattered_relocation_info<P>* sreloc = (const macho_scattered_relocation_info<P>*)reloc;
+               if ( sreloc->r_length() != 2 ) 
+                       throw "bad local scattered relocation length";
+               if ( sreloc->r_type() != ARM_RELOC_PB_LA_PTR ) 
+                       throw "bad local scattered relocation type";
+       }
+       else {
+               if ( reloc->r_length() != 2 ) 
+                       throw "bad local relocation length";
+               if ( reloc->r_extern() != 0 ) 
+                       throw "external relocation found with local relocations";
+               if ( ! this->addressInWritableSegment(reloc->r_address() + this->relocBase()) )
+                       throw "local relocation address not in writable segment";
+       }
+}
 
 template <typename A>
 void MachOChecker<A>::checkRelocations()
@@ -805,6 +899,12 @@ static void check(const char* path)
                                        else
                                                throw "in universal file, x86_64 slice does not contain x86_64 mach-o";
                                        break;
+                               case CPU_TYPE_ARM:
+                                       if ( MachOChecker<arm>::validFile(p + offset) )
+                                               MachOChecker<arm>::make(p + offset, size, path);
+                                       else
+                                               throw "in universal file, arm slice does not contain arm mach-o";
+                                       break;
                                default:
                                                throwf("in universal file, unknown architecture slice 0x%x\n", cputype);
                                }
@@ -822,6 +922,9 @@ static void check(const char* path)
                else if ( MachOChecker<x86_64>::validFile(p) ) {
                        MachOChecker<x86_64>::make(p, length, path);
                }
+               else if ( MachOChecker<arm>::validFile(p) ) {
+                       MachOChecker<arm>::make(p, length, path);
+               }
                else {
                        throw "not a known file type";
                }
old mode 100644 (file)
new mode 100755 (executable)
index e47ce34..ad9b905
 #include <fcntl.h>
 #include <errno.h>
 #include <unistd.h>
-#include <mach-o/loader.h>
-#include <mach-o/fat.h>
-#include <mach-o/reloc.h>
-#include <mach-o/ppc/reloc.h>
-#include <mach-o/x86_64/reloc.h>
 #include <vector>
 #include <set>
 
+
 #include "MachOFileAbstraction.hpp"
 #include "Architectures.hpp"
 
-
 static bool verbose = false;
 
 __attribute__((noreturn))
@@ -164,6 +159,9 @@ MultiArchRebaser::MultiArchRebaser(const char* path, bool writable)
                                        case CPU_TYPE_X86_64:
                                                fRebasers.push_back(new Rebaser<x86_64>(&p[fileOffset]));
                                                break;
+                                       case CPU_TYPE_ARM:
+                                               fRebasers.push_back(new Rebaser<arm>(&p[fileOffset]));
+                                               break;
                                        default:
                                                throw "unknown file format";
                                }
@@ -187,6 +185,9 @@ MultiArchRebaser::MultiArchRebaser(const char* path, bool writable)
                        else if ( (OSSwapLittleToHostInt32(mh->magic) == MH_MAGIC_64) && (OSSwapLittleToHostInt32(mh->cputype) == CPU_TYPE_X86_64)) {
                                fRebasers.push_back(new Rebaser<x86_64>(mh));
                        }
+                       else if ( (OSSwapLittleToHostInt32(mh->magic) == MH_MAGIC) && (OSSwapLittleToHostInt32(mh->cputype) == CPU_TYPE_ARM)) {
+                               fRebasers.push_back(new Rebaser<arm>(mh));
+                       }
                        else {
                                throw "unknown file format";
                        }
@@ -234,7 +235,7 @@ template <> cpu_type_t Rebaser<ppc>::getArchitecture()    const { return CPU_TYP
 template <> cpu_type_t Rebaser<ppc64>::getArchitecture()  const { return CPU_TYPE_POWERPC64; }
 template <> cpu_type_t Rebaser<x86>::getArchitecture()    const { return CPU_TYPE_I386; }
 template <> cpu_type_t Rebaser<x86_64>::getArchitecture() const { return CPU_TYPE_X86_64; }
-
+template <> cpu_type_t Rebaser<arm>::getArchitecture() const { return CPU_TYPE_ARM; }
 
 template <typename A>
 uint64_t Rebaser<A>::getBaseAddress() const
@@ -527,6 +528,26 @@ void Rebaser<x86>::doLocalRelocation(const macho_relocation_info<P>* reloc)
        }
 }
 
+template <>
+void Rebaser<arm>::doLocalRelocation(const macho_relocation_info<P>* reloc)
+{
+       if ( (reloc->r_address() & R_SCATTERED) == 0 ) {
+               if ( reloc->r_type() == ARM_RELOC_VANILLA ) {
+                       pint_t* addr = mappedAddressForVMAddress(reloc->r_address() + fOrignalVMRelocBaseAddress);
+                       P::setP(*addr, P::getP(*addr) + fSlide);
+               }
+       }
+       else {
+               macho_scattered_relocation_info<P>* sreloc = (macho_scattered_relocation_info<P>*)reloc;
+               if ( sreloc->r_type() == ARM_RELOC_PB_LA_PTR ) {
+                       sreloc->set_r_value( sreloc->r_value() + fSlide );
+               }
+               else {
+                       throw "cannot rebase final linked image with scattered relocations";
+               }
+       }
+}
+
 template <typename A>
 void Rebaser<A>::doLocalRelocation(const macho_relocation_info<P>* reloc)
 {
@@ -709,6 +730,8 @@ static const char* nameForArch(cpu_type_t arch)
                        return "i386";
                case CPU_TYPE_X86_64:
                        return "x86_64";
+               case CPU_TYPE_ARM:
+                       return "arm";
        }
        return "unknown";
 }
@@ -801,6 +824,14 @@ static uint64_t startAddress(cpu_type_t arch, std::vector<fileInfo>& files, uint
                else if ( arch == CPU_TYPE_X86_64 ) {
                        return 0x200000000ULL;
                }
+               else if ( arch == CPU_TYPE_ARM ) {
+                       // place dylibs below dyld
+                       uint64_t topAddr = 0x2FE00000;
+                       uint64_t totalSize = totalVMSize(arch, files);
+                       if ( totalSize > topAddr )
+                               throwf("total size of images (0x%X) does not fit below 0x2FE00000", totalSize);
+                       return topAddr - totalSize;
+               }
                else
                        throw "unknown architecture";
        }
@@ -844,6 +875,10 @@ int main(int argc, const char* argv[])
                                                onlyArchs.insert(CPU_TYPE_I386);
                                        else if ( strcmp(arch, "x86_64") == 0 )
                                                onlyArchs.insert(CPU_TYPE_X86_64);
+                                       else if ( strcmp(arch, "arm") == 0 )
+                                               onlyArchs.insert(CPU_TYPE_ARM);
+                                       else if ( strcmp(arch, "armv6") == 0 )
+                                               onlyArchs.insert(CPU_TYPE_ARM);
                                        else 
                                                throwf("unknown architecture %s", arch);
                                }
@@ -866,6 +901,7 @@ int main(int argc, const char* argv[])
                        onlyArchs.insert(CPU_TYPE_POWERPC64);
                        onlyArchs.insert(CPU_TYPE_I386);
                        onlyArchs.insert(CPU_TYPE_X86_64);
+                       onlyArchs.insert(CPU_TYPE_ARM);
                }
                
                // scan files and collect sizes
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 8462385..70e05f8
@@ -6,7 +6,7 @@ SHELL = /bin/sh
 ARCH ?= $(shell arch)
 
 # set default to be all
-VALID_ARCHS ?= "ppc ppc64 i386 x86_64"
+VALID_ARCHS ?= "ppc ppc64 i386 x86_64 armv6"
 
 MYDIR=$(shell cd ../../bin;pwd)
 
@@ -15,8 +15,14 @@ ifdef BUILT_PRODUCTS_DIR
        PATH := ${BUILT_PRODUCTS_DIR}:${MYDIR}:${PATH}
        COMPILER_PATH := ${BUILT_PRODUCTS_DIR}:${MYDIR}:${COMPILER_PATH}
 else
-       PATH := ${MYDIR}:${PATH}:
-       COMPILER_PATH := ${MYDIR}:${COMPILER_PATH}:
+       ifneq "$(findstring /unit-tests/test-cases/, $(shell pwd))" ""
+               RELEASEDIR=$(shell cd ../../../build/Release;pwd)
+               PATH := ${RELEASEDIR}:${MYDIR}:${PATH}
+               COMPILER_PATH := ${RELEASEDIR}:${MYDIR}:${COMPILER_PATH}
+       else
+               PATH := ${MYDIR}:${PATH}:
+               COMPILER_PATH := ${MYDIR}:${COMPILER_PATH}:
+       endif
 endif
 export PATH
 export COMPILER_PATH
@@ -33,6 +39,23 @@ ASMFLAGS =
 CXX              = g++-4.0 -arch ${ARCH}
 CXXFLAGS = -Wall
 
+ifeq ($(ARCH),armv6)
+  LDFLAGS := -syslibroot /Developer/SDKs/Purple
+  override FILEARCH = arm
+else
+  FILEARCH = $(ARCH)
+endif
+
+ifeq ($(ARCH),thumb)
+  LDFLAGS := -syslibroot /Developer/SDKs/Purple
+  CCFLAGS += -mthumb
+  CXXFLAGS += -mthumb
+  override ARCH = armv6
+  override FILEARCH = arm
+else
+  FILEARCH = $(ARCH)
+endif
+
 RM      = rm
 RMFLAGS = -rf
 
old mode 100644 (file)
new mode 100755 (executable)
index 945df480e82852770d610fc6dfb64153485624c3..4ee740337b4f0ea0812e8f9ea4a7cdb50bedb693 100755 (executable)
@@ -1,11 +1,18 @@
 #!/bin/sh
 
+unset RC_TRACE_DYLIBS
+unset RC_TRACE_ARCHIVES
+unset LD_TRACE_DYLIBS
+unset LD_TRACE_ARCHIVES
+
+export DYLD_FALLBACK_LIBRARY_PATH=${DYLD_FALLBACK_LIBRARY_PATH}:/Developer/usr/lib
 # cd into test-cases directory
 cd `echo "$0" | sed 's/run-all-unit-tests/test-cases/'`
 
 [ "$PROCTORRUN" ] && exec ../proctor-run
 
-all_archs="ppc ppc64 i386 x86_64"
+all_archs="x86_64 armv6 thumb ppc ppc64 i386  "
+valid_archs="x86_64 armv6 ppc ppc64 i386  "
 
 mkdir /tmp/$$
 for arch in $all_archs
@@ -16,7 +23,7 @@ do
        # build architecture
        [ "$NEWTEST" ] && NT=-newtest
 
-       ../bin/make-recursive$NT.pl ARCH=$arch VALID_ARCHS="$all_archs" | ../bin/result-filter.pl
+       ../bin/make-recursive$NT.pl ARCH=$arch VALID_ARCHS="$valid_archs" | ../bin/result-filter.pl
 
        # clean up so svn is happy
        ../bin/make-recursive.pl ARCH=$arch clean > /dev/null
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 065b6f3..806c64e
@@ -30,10 +30,10 @@ include ${TESTROOT}/include/common.makefile
 all:
        ${CC} ${CCFLAGS} main.c -static -c
        ${CC} ${CCFLAGS} abs.s -static -c
-       ${LD} -arch ${ARCH} -static main.o abs.o -e _main -o main
-       ${LD} -arch ${ARCH} -static -r main.o abs.o -o all.o
+       ${LD} -arch ${ARCH} -static main.o abs.o -e _main -o main -new_linker
+       ${LD} -arch ${ARCH} -static -r main.o abs.o -o all.o -new_linker
        nm -m all.o | grep _myAbs | grep absolute | ${FAIL_IF_EMPTY}
-       ${LD} -arch ${ARCH} -static all.o -e _main -o main2
+       ${LD} -arch ${ARCH} -static all.o -e _main -o main2 -new_linker
        ${PASS_IFF_GOOD_MACHO} main2
        
 clean:
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index f5e0e24..892043d
@@ -38,7 +38,7 @@ all:
        ${CC} ${CCFLAGS} baz.m -c -o baz-${ARCH}.o 
        ${FAIL_IF_BAD_OBJ} baz-${ARCH}.o
        libtool -static foo-${ARCH}.o bar-${ARCH}.o baz-${ARCH}.o -o libfoobarbaz-${ARCH}.a
-       ${CC} ${CCFLAGS} main.c -lfoobarbaz-${ARCH} -L. -o main-${ARCH} -ObjC -framework Foundation
+       ${CC} ${CCFLAGS} main.c -lfoobarbaz-${ARCH} -L. -o main-${ARCH} -ObjC -framework Foundation -framework CoreFoundation
        ${FAIL_IF_BAD_MACHO} main-${ARCH}
        nm main-${ARCH} | grep "_bar" | ${FAIL_IF_STDIN}
        nm main-${ARCH} | grep "_Foo" | ${FAIL_IF_EMPTY}
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 3c8b3e5..3b1cc7c
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
+# Copyright (c) 2006-2007 Apple Inc. All rights reserved.
 #
 # @APPLE_LICENSE_HEADER_START@
 # 
 TESTROOT = ../..
 include ${TESTROOT}/include/common.makefile
 
-SHELL = bash # use bash shell so we can redirect just stderr
 
 #
-# The point of this test is a check that ld
-# can figure out which architecture is needed 
-# by looking at the .o files when -arch is not used.
+# Check that ld can figure out architecture from .o files without -arch option
 #
 
 run: all
 
 all:
-       ${CC} ${CCFLAGS} hello.c -c -o hello.o  -mmacosx-version-min=10.4
+       ${CC} ${CCFLAGS} hello.c -c -o hello.o 
        ${FAIL_IF_BAD_OBJ} hello.o
-       ${LD} -r -lcrt1.o hello.o -o hello-r.o -lSystem
-       ${FAIL_IF_ERROR} ${OBJECTDUMP} hello-r.o >/dev/null
-       file hello-r.o | grep ${ARCH} | ${PASS_IFF_STDIN}
+       ${LD} ${LDFLAGS} -lcrt1.o hello.o -o hello -lSystem
+       file hello | grep ${FILEARCH} | ${PASS_IFF_STDIN}
 
 clean:
-       rm -rf *.o
+       rm -rf hello.o hello
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/auto-arch2/Makefile b/unit-tests/test-cases/auto-arch2/Makefile
deleted file mode 100644 (file)
index a6f2520..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-##
-# Copyright (c) 2006 Apple Computer, 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
-
-SHELL = bash # use bash shell so we can redirect just stderr
-
-#
-# The point of this test is a check that ld
-# can figure out which architecture is needed 
-# by looking at the .o files when -arch is not used.
-#
-
-run: all
-
-
-all:
-       ${CC} ${CCFLAGS} hello.c -c -o hello-${ARCH}.o -mmacosx-version-min=10.4
-       ${FAIL_IF_BAD_OBJ} hello-${ARCH}.o
-       ${FAIL_IF_ERROR} ${LD} -r -lcrt1.o hello-${ARCH}.o -o hello-r.o -lSystem
-       ${FAIL_IF_ERROR} ObjectDump hello-r.o >/dev/null
-       file hello-r.o | grep ${ARCH} | ${PASS_IFF_STDIN}
-
-clean:
-       rm -f *.o
diff --git a/unit-tests/test-cases/auto-arch2/comment.txt b/unit-tests/test-cases/auto-arch2/comment.txt
deleted file mode 100644 (file)
index ed107a9..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-The point of this test is a check that ld
-can figure out which architecture is needed 
-by looking at the .o files when -arch is not used.
diff --git a/unit-tests/test-cases/auto-arch2/hello.c b/unit-tests/test-cases/auto-arch2/hello.c
deleted file mode 100644 (file)
index 14d9363..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
- *
- * Copyright (c) 2006 Apple Computer, 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>
-
-int main()
-{
-       fprintf(stdout, "hello\n");
-}
old mode 100644 (file)
new mode 100755 (executable)
index b99e085..346e2b7
@@ -23,7 +23,6 @@
 TESTROOT = ../..
 include ${TESTROOT}/include/common.makefile
 
-
 ALL_ARCH_OPTIONS = $(patsubst %,-arch %,$(VALID_ARCHS))
 
 #
@@ -59,4 +58,4 @@ all:
        
 
 clean:
-       rm -rf *.dylib main
+       rm -rf libfoo.dylib main
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index c0163d0..96d83b8
 TESTROOT = ../..
 include ${TESTROOT}/include/common.makefile
 
+SHELL = bash # use bash shell so we can redirect just stderr
+
+#
+# Ccheck that ld -bundle_loader works with bundles and executable, 
+# and _bar is found in the loader and not in libbar.dylib
 #
-# The point of this test is a sanity check that ld
-# -bundle_loader works, and _bar is found in the executable
-# and not in libbar.dylib
 
 run: all
 
 all:
        ${CC} ${CCFLAGS} bar.c -dynamiclib -o libbar.dylib
        ${FAIL_IF_BAD_MACHO} libbar.dylib
+       # test with loader as main executable
        ${CC} ${CCFLAGS} main.c bar.c -o main
        ${FAIL_IF_BAD_MACHO} main
        ${CC} ${CCFLAGS} bundle.c -bundle -bundle_loader main libbar.dylib -o bundle.bundle
        ${FAIL_IF_BAD_MACHO} bundle.bundle
        nm -m bundle.bundle | grep _bar | grep "from executable" | ${PASS_IFF_STDIN}
+       # test with loader as another bundle
+       ${CC} ${CCFLAGS} -bundle main.c bar.c -o mainbundle
+       ${FAIL_IF_BAD_MACHO} main
+       ${CC} ${CCFLAGS} bundle.c -bundle -bundle_loader mainbundle libbar.dylib -o bundle.bundle
+       ${FAIL_IF_BAD_MACHO} bundle.bundle
+       nm -m bundle.bundle | grep _bar | grep "from executable" | ${PASS_IFF_STDIN}
+       # verify error message when linking with raw bundle
+       ${FAIL_IF_SUCCESS} ${CC} ${CCFLAGS} main.c bar.c -o main bundle.bundle 2> error.log
+       grep "link with bundle" error.log | ${PASS_IFF_STDIN}
 
 clean:
-       rm *.dylib main bundle.bundle
+       rm *.dylib main bundle.bundle mainbundle error.log
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/bundle_loader/comment.txt b/unit-tests/test-cases/bundle_loader/comment.txt
deleted file mode 100644 (file)
index e406042..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-The point of this test is a sanity check that ld
--bundle_loader works, and _bar is found in the executable
-and not in libbar.dylib
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/cfstring-coalesce/Makefile b/unit-tests/test-cases/cfstring-coalesce/Makefile
new file mode 100755 (executable)
index 0000000..c1ca816
--- /dev/null
@@ -0,0 +1,52 @@
+##
+# Copyright (c) 2007 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 cfstring literals are coalesced and dead stripped
+# There is 3 CFSTR in foo.c and 1 CFSTR in bar.c
+# After coalescing and dead stripping there should be only one CFSTR in the output
+#
+
+ifeq (,${findstring 64,$(ARCH)})
+       CFSTRING_SIZE = 16
+       CFSTRING_SIZE_WRITABLE = 32
+else
+       CFSTRING_SIZE = 32
+       CFSTRING_SIZE_WRITABLE = 64
+endif
+
+
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} foo.c bar.c -o foo -framework CoreFoundation -dead_strip
+       size -l foo | grep "__cfstring: ${CFSTRING_SIZE}" | ${FAIL_IF_EMPTY}
+       # now try with -fwritable-strings
+       ${CC} ${CCFLAGS} foo.c bar.c -o foo_writable -framework CoreFoundation -dead_strip -fwritable-strings
+       size -l foo_writable | grep "__cfstring: ${CFSTRING_SIZE_WRITABLE}" | ${PASS_IFF_STDIN}
+
+clean:
+       rm -rf foo foo_writable
diff --git a/unit-tests/test-cases/cfstring-coalesce/bar.c b/unit-tests/test-cases/cfstring-coalesce/bar.c
new file mode 100755 (executable)
index 0000000..9a84abd
--- /dev/null
@@ -0,0 +1,7 @@
+#include <CoreFoundation/CFString.h>
+
+
+void bar()
+{
+       CFStringGetLength(CFSTR("live"));
+}
diff --git a/unit-tests/test-cases/cfstring-coalesce/foo.c b/unit-tests/test-cases/cfstring-coalesce/foo.c
new file mode 100755 (executable)
index 0000000..fe1b30e
--- /dev/null
@@ -0,0 +1,19 @@
+#include <CoreFoundation/CFString.h>
+
+extern void bar();
+
+void foo()
+{
+       CFStringGetLength(CFSTR("hello"));
+       CFStringGetLength(CFSTR("world"));
+}
+
+
+int main() 
+{
+       CFStringGetLength(CFSTR("live"));
+       bar();
+       return 0; 
+}
+
+
diff --git a/unit-tests/test-cases/cfstring-utf16/Makefile b/unit-tests/test-cases/cfstring-utf16/Makefile
new file mode 100755 (executable)
index 0000000..3375aae
--- /dev/null
@@ -0,0 +1,50 @@
+##
+# Copyright (c) 2008 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 utf16 cfstring literals are not 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
+#
+
+ifeq (,${findstring 64,$(ARCH)})
+       CFSTRING_SIZE = 48
+else
+       CFSTRING_SIZE = 96
+endif
+       USTRING_SIZE = 37
+
+
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} foo.m bar.m -o foo -framework CoreFoundation -dead_strip
+       size -l foo | grep "__cfstring: ${CFSTRING_SIZE}" | ${FAIL_IF_EMPTY}
+       size -l foo | grep "__ustring: ${USTRING_SIZE}" | ${FAIL_IF_EMPTY}
+       ${PASS_IFF_GOOD_MACHO} foo
+
+clean:
+       rm -rf foo 
diff --git a/unit-tests/test-cases/cfstring-utf16/bar.m b/unit-tests/test-cases/cfstring-utf16/bar.m
new file mode 100755 (executable)
index 0000000..bdf5168
--- /dev/null
@@ -0,0 +1,7 @@
+#include <CoreFoundation/CFString.h>
+
+
+void bar()
+{
+       CFStringGetLength(CFSTR("über"));
+}
diff --git a/unit-tests/test-cases/cfstring-utf16/foo.m b/unit-tests/test-cases/cfstring-utf16/foo.m
new file mode 100755 (executable)
index 0000000..6e4c268
--- /dev/null
@@ -0,0 +1,20 @@
+#include <CoreFoundation/CFString.h>
+
+extern void bar();
+
+void foo()
+{
+       CFStringGetLength(CFSTR("hello"));
+       CFStringGetLength(CFSTR("überhund"));
+}
+
+
+int main() 
+{
+       CFStringGetLength(CFSTR("über"));
+       CFStringGetLength(CFSTR("überhund"));
+       bar();
+       return 0; 
+}
+
+
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 68e282d..68d809c
@@ -30,7 +30,7 @@ include ${TESTROOT}/include/common.makefile
 #
 
 all:
-       ${CC} baz.c -fno-common -c -o baz.o
+       ${CC} ${CCFLAGS} baz.c -fno-common -c -o baz.o
        ${CC} ${CCFLAGS} main.c foo.c bar.c baz.o -o main -mmacosx-version-min=10.5
        nm -j -n main | grep _common > symbol.order
        ${FAIL_IF_ERROR} diff symbol.order expected.order
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/cpu-sub-types-preference/Makefile b/unit-tests/test-cases/cpu-sub-types-preference/Makefile
new file mode 100755 (executable)
index 0000000..7586a51
--- /dev/null
@@ -0,0 +1,96 @@
+##
+# Copyright (c) 2008 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 cpu subtype preference
+#
+
+test: test-${ARCH}
+
+test-ppc64:
+       ${PASS_IFF} true
+
+test-i386:
+       ${PASS_IFF} true
+
+test-x86_64:
+       ${PASS_IFF} true
+
+test-armv6:
+       gcc foo.c -arch armv4t -c -DAAA=1 -o foo4.o
+       gcc foo.c -arch armv5 -c -DBBB=1 -o foo5.o
+       gcc foo.c -arch armv6 -c -DCCC=1 -o foo6.o
+       gcc foo.c -arch xscale -c -DDDD=1 -o foox.o
+       lipo foo4.o foo5.o foo6.o foox.o -create -output foo.o
+       
+       # check -arch armv4t pulls out V4 slice
+       ${LD} -r -arch armv4t foo.o -o fooa.o
+       otool -hv fooa.o | grep V4T | ${FAIL_IF_EMPTY}
+       nm fooa.o | grep _aaa | ${FAIL_IF_EMPTY}
+
+       # check -arch armv5 pulls out V5 slice
+       ${LD} -r -arch armv5 foo.o -o foob.o
+       otool -hv foob.o | grep V5 | ${FAIL_IF_EMPTY}
+       nm foob.o | grep _bbb | ${FAIL_IF_EMPTY}
+
+       # check -arch armv6 pulls out V6 slice
+       ${LD} -r -arch armv6 foo.o -o fooc.o
+       otool -hv fooc.o | grep V6 | ${FAIL_IF_EMPTY}
+       nm fooc.o | grep _ccc | ${FAIL_IF_EMPTY}
+
+       # check -arch xscale pulls out xscale slice
+       ${LD} -r -arch xscale foo.o -o fooxx.o
+       otool -hv fooxx.o | grep XSCALE | ${FAIL_IF_EMPTY}
+       nm fooxx.o | grep _ddd | ${FAIL_IF_EMPTY}
+
+       ${PASS_IFF} true
+
+
+test-ppc:
+       gcc foo.c -arch ppc750 -c -DAAA=1 -o foog3.o
+       gcc foo.c -arch ppc7400 -c -DBBB=1 -o foog4.o
+       gcc foo.c -arch ppc970 -c -DCCC=1 -o foog5.o
+       lipo foog3.o foog4.o foog5.o -create -output foo.o
+       
+       # check -arch ppc750 pulls out g3 slice
+       ${LD} -r -arch ppc750 foo.o -o fooa.o
+       otool -hv fooa.o | grep ppc750 | ${FAIL_IF_EMPTY}
+       nm fooa.o | grep _aaa | ${FAIL_IF_EMPTY}
+
+       # check -arch ppc7400 pulls out g4 slice
+       ${LD} -r -arch ppc7400 foo.o -o foob.o
+       otool -hv foob.o | grep ppc7400 | ${FAIL_IF_EMPTY}
+       nm foob.o | grep _bbb | ${FAIL_IF_EMPTY}
+
+       # check -arch ppc970 pulls out g5 slice
+       ${LD} -r -arch ppc970 foo.o -o fooc.o
+       otool -hv fooc.o | grep ppc970 | ${FAIL_IF_EMPTY}
+       nm fooc.o | grep _ccc | ${FAIL_IF_EMPTY}
+
+       ${PASS_IFF} true
+
+
+clean:
+       rm -f *.o
diff --git a/unit-tests/test-cases/cpu-sub-types-preference/foo.c b/unit-tests/test-cases/cpu-sub-types-preference/foo.c
new file mode 100755 (executable)
index 0000000..983ed81
--- /dev/null
@@ -0,0 +1,25 @@
+
+
+#if AAA
+       void aaa() {}
+#endif
+
+#if BBB
+       void bbb() {}
+#endif
+
+#if CCC
+       void ccc() {}
+#endif
+
+#if DDD
+       void ddd() {}
+#endif
+
+#if EEE
+       void eee() {}
+#endif
+
+#if FFFF
+       void fff() {}
+#endif
old mode 100644 (file)
new mode 100755 (executable)
index 50f05e9..695ffba
@@ -24,7 +24,7 @@ TESTROOT = ../..
 include ${TESTROOT}/include/common.makefile
 
 #
-# The point of this test is validate cpu subtypes processing
+# Validate cpu subtypes processing
 #
 
 test: test-${ARCH}
@@ -38,18 +38,84 @@ test-i386:
 test-x86_64:
        ${PASS_IFF} true
 
+test-armv6:
+       gcc  foo.c -arch armv4t -c -o foo-v4.o
+       ${FAIL_IF_BAD_OBJ} foo-v4.o
+       gcc  foo.c -arch armv5  -c -o foo-v5.o
+       ${FAIL_IF_BAD_OBJ} foo-v5.o
+       gcc  foo.c -arch armv6  -c -o foo-v6.o
+       ${FAIL_IF_BAD_OBJ} foo-v6.o
+       gcc  foo.c -arch xscale  -c -o foo-xscale.o
+       ${FAIL_IF_BAD_OBJ} foo-xscale.o
+       gcc  main.c -arch armv4t  -c -o main-v4.o
+       ${FAIL_IF_BAD_OBJ} main-v4.o
+       gcc  main.c -arch armv5  -c -o main-v5.o
+       ${FAIL_IF_BAD_OBJ} main-v5.o
+       gcc  main.c -arch armv6  -c -o main-v6.o
+       ${FAIL_IF_BAD_OBJ} main-v6.o
+       gcc  main.c -arch xscale  -c -o main-xscale.o
+       ${FAIL_IF_BAD_OBJ} main-xscale.o
+
+       # check V4+V4 -> V4
+       ${LD} -r main-v4.o foo-v4.o -o all.o
+       ${FAIL_IF_BAD_OBJ} all.o
+       otool -hv all.o | grep V4T | ${FAIL_IF_EMPTY}
+
+       # check V4+V5 -> V5
+       ${LD} -r main-v4.o foo-v5.o -o all.o
+       ${FAIL_IF_BAD_OBJ} all.o
+       otool -hv all.o | grep V5 | ${FAIL_IF_EMPTY}
+
+       # check V4+V6 -> V6
+       ${LD} -r main-v4.o foo-v6.o -o all.o
+       ${FAIL_IF_BAD_OBJ} all.o
+       otool -hv all.o | grep V6 | ${FAIL_IF_EMPTY}
+
+       # check V4+xscale -> xscale
+       ${LD} -r main-v4.o foo-xscale.o -o all.o
+       ${FAIL_IF_BAD_OBJ} all.o
+       otool -hv all.o | grep XSCALE | ${FAIL_IF_EMPTY}
+
+       # check V5+V5 -> V5
+       ${LD} -r main-v5.o foo-v5.o -o all.o
+       ${FAIL_IF_BAD_OBJ} all.o
+       otool -hv all.o | grep V5 | ${FAIL_IF_EMPTY}
+
+       # check V5+V6 -> V6
+       ${LD} -r main-v5.o foo-v6.o -o all.o
+       ${FAIL_IF_BAD_OBJ} all.o
+       otool -hv all.o | grep V6 | ${FAIL_IF_EMPTY}
+
+       # check V5+xscale -> xscale
+       ${LD} -r main-v5.o foo-xscale.o -o all.o
+       ${FAIL_IF_BAD_OBJ} all.o
+       otool -hv all.o | grep XSCALE | ${FAIL_IF_EMPTY}
+
+       # check V6+V6 -> V6
+       ${LD} -r main-v6.o foo-v6.o -o all.o
+       ${FAIL_IF_BAD_OBJ} all.o
+       otool -hv all.o | grep V6 | ${FAIL_IF_EMPTY}
+
+       # check xscale+xscale -> xscale
+       ${LD} -r main-xscale.o foo-xscale.o -o all.o
+       ${FAIL_IF_BAD_OBJ} all.o
+       otool -hv all.o | grep XSCALE | ${FAIL_IF_EMPTY}
+
+       ${PASS_IFF} true
+
+
 test-ppc:
-       gcc foo.c -arch ppc     -mmacosx-version-min=10.4 -c -o foo.o
+       gcc  foo.c -arch ppc  -mmacosx-version-min=10.4   -c -o foo.o
        ${FAIL_IF_BAD_OBJ} foo.o
-       gcc foo.c -arch ppc750  -mmacosx-version-min=10.4 -c -o foo-G3.o
+       gcc  foo.c -arch ppc750  -c -o foo-G3.o
        ${FAIL_IF_BAD_OBJ} foo-G3.o
-       gcc foo.c -arch ppc7400 -mmacosx-version-min=10.4 -c -o foo-G4.o
+       gcc  foo.c -arch ppc7400 -c -o foo-G4.o
        ${FAIL_IF_BAD_OBJ} foo-G4.o
-       gcc foo.c -arch ppc970  -mmacosx-version-min=10.4 -c -o foo-G5.o
+       gcc  foo.c -arch ppc970  -c -o foo-G5.o
        ${FAIL_IF_BAD_OBJ} foo-G5.o
-       gcc main.c -arch ppc    -mmacosx-version-min=10.4 -c -o main.o
+       gcc  main.c -arch ppc   -mmacosx-version-min=10.4  -c -o main.o
        ${FAIL_IF_BAD_OBJ} main.o
-       gcc main.c -arch ppc970 -mmacosx-version-min=10.4 -c -o main-G5.o
+       gcc  main.c -arch ppc970 -c -o main-G5.o
        ${FAIL_IF_BAD_OBJ} main-G5.o
 
        # check ALL+ALL -> ALL
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/dead_strip-init-archive/Makefile b/unit-tests/test-cases/dead_strip-init-archive/Makefile
new file mode 100755 (executable)
index 0000000..4b4f912
--- /dev/null
@@ -0,0 +1,40 @@
+##
+# Copyright (c) 2007 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
+
+#
+# Tests that a -init function can be pulled from an archive when using -dead_strip.
+#
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} foo.c -c -o foo.o
+       libtool -static foo.o -o libfoo.a
+       ${FAIL_IF_ERROR} ${CC} ${CCFLAGS}  bar.c -dynamiclib  -Os libfoo.a -dead_strip -o libbar.dylib -init _foo 
+       ${PASS_IFF_GOOD_MACHO} libbar.dylib
+
+clean:
+       rm -rf libbar.dylib libfoo.a foo.o
+
diff --git a/unit-tests/test-cases/dead_strip-init-archive/bar.c b/unit-tests/test-cases/dead_strip-init-archive/bar.c
new file mode 100755 (executable)
index 0000000..b348aa8
--- /dev/null
@@ -0,0 +1,4 @@
+
+void bar() {}
+
+
diff --git a/unit-tests/test-cases/dead_strip-init-archive/foo.c b/unit-tests/test-cases/dead_strip-init-archive/foo.c
new file mode 100755 (executable)
index 0000000..95ec91c
--- /dev/null
@@ -0,0 +1,6 @@
+
+
+void foo() {}
+
+
+
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/dtrace-static-probes-coalescing/Makefile b/unit-tests/test-cases/dtrace-static-probes-coalescing/Makefile
new file mode 100755 (executable)
index 0000000..533169f
--- /dev/null
@@ -0,0 +1,59 @@
+##
+# Copyright (c) 2007 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 C++ coalescing throws away static probes associated
+# with weak functions that are coalesced away.
+# Build two programs that both should have the same number of probes
+# and hence the same DOF section size
+#
+
+all: simp coal
+       otool -lv coal | grep -A3 __dof_Number | grep size > coal-dof-size
+       otool -lv simp | grep -A3 __dof_Number | grep size > simp-dof-size
+       ${PASS_IFF_SUCCESS} diff coal-dof-size simp-dof-size
+
+Number.h:      Number.d
+       dtrace -h -s Number.d
+
+a.o : a.cxx Number.h header.h
+       ${CXX} ${CXXFLAGS} -c -DFUNC=a a.cxx -o a.o
+       
+b.o : a.cxx Number.h header.h
+       ${CXX} ${CXXFLAGS} -c -DFUNC=b a.cxx -o b.o
+       
+c.o : a.cxx Number.h header.h
+       ${CXX} ${CXXFLAGS} -c -DFUNC=c a.cxx -o c.o
+
+coal : a.o b.o c.o
+       ${CXX} -dynamiclib a.o b.o c.o -o coal
+       
+simp : x.cxx Number.h
+       ${CXX} -dynamiclib x.cxx -o simp
+
+
+
+clean:
+       rm -rf coal simp a.o b.o c.o Number.h coal-dof-size simp-dof-size
diff --git a/unit-tests/test-cases/dtrace-static-probes-coalescing/Number.d b/unit-tests/test-cases/dtrace-static-probes-coalescing/Number.d
new file mode 100755 (executable)
index 0000000..9383fe4
--- /dev/null
@@ -0,0 +1,3 @@
+provider Number {
+    probe hit(int value);
+};
diff --git a/unit-tests/test-cases/dtrace-static-probes-coalescing/a.cxx b/unit-tests/test-cases/dtrace-static-probes-coalescing/a.cxx
new file mode 100755 (executable)
index 0000000..8e7e3c6
--- /dev/null
@@ -0,0 +1,8 @@
+
+#include <stdio.h>
+
+#include "header.h"
+
+
+void FUNC() { foo(); }
+
diff --git a/unit-tests/test-cases/dtrace-static-probes-coalescing/header.h b/unit-tests/test-cases/dtrace-static-probes-coalescing/header.h
new file mode 100755 (executable)
index 0000000..162419b
--- /dev/null
@@ -0,0 +1,11 @@
+
+#include "Number.h"
+
+#define LOTS_O_PROBES  { NUMBER_HIT(1); NUMBER_HIT(2); NUMBER_HIT(3); NUMBER_HIT(4); }
+
+
+inline void foo() { 
+       LOTS_O_PROBES 
+}
+
+
diff --git a/unit-tests/test-cases/dtrace-static-probes-coalescing/x.cxx b/unit-tests/test-cases/dtrace-static-probes-coalescing/x.cxx
new file mode 100755 (executable)
index 0000000..b756394
--- /dev/null
@@ -0,0 +1,6 @@
+
+#include "header.h"
+
+void f() { LOTS_O_PROBES }
+
+
old mode 100644 (file)
new mode 100755 (executable)
index 5046ea1..b59760f
@@ -35,20 +35,20 @@ run: main main-r main-dead_strip libmain.dylib
        ${PASS_IFF_GOOD_MACHO} main-r
 
 main: main.c foo.h bar.h
-       ${CC} main.c -o main 
+       ${CC} ${CCFLAGS} main.c -o main 
 
 main-dead_strip: main.c foo.h bar.h
-       ${CC} main.c -o main-dead_strip -dead_strip 
+       ${CC} ${CCFLAGS} main.c -o main-dead_strip -dead_strip 
 
 main-r: main.c foo.h bar.h
-       ${CC} main.c -c -o main.o 
+       ${CC} ${CCFLAGS} main.c -c -o main.o 
        #${FAIL_IF_BAD_OBJ} main.o
        ${LD} -r main.o -o main-r.o 
        #${FAIL_IF_BAD_OBJ} main-r.o
-       ${CC} main-r.o -o main-r
+       ${CC} ${CCFLAGS} main-r.o -o main-r
 
 libmain.dylib: main.c foo.h bar.h
-       ${CC} main.c -dynamiclib -o libmain.dylib 
+       ${CC} ${CCFLAGS} main.c -dynamiclib -o libmain.dylib 
 
 foo.h: foo.d
        dtrace -h -s foo.d
@@ -57,4 +57,4 @@ bar.h:        bar.d
        dtrace -h -s bar.d
 
 clean:
-       rm -rf main main main-r main-dead_strip foo.h bar.h *.o
+       rm -rf main libmain.dylib main-r main-dead_strip foo.h bar.h *.o
old mode 100644 (file)
new mode 100755 (executable)
index bbce55f..8a417e9
@@ -11,6 +11,7 @@ typedef int weirdType2;
 int deadwood()
 {
        BAR_COUNT1(2);
+       return 0;
 }
 
 
old mode 100644 (file)
new mode 100755 (executable)
index 38f4c8c..4ab634d
 0000   FUN __Z3bari
 0000   FUN 
 0000 ENSYM 
+0000 BNSYM 
+0000   FUN .my_non_standard_function_name
+0000   FUN 
+0000 ENSYM 
 0000  GSYM _init
+0000 STSYM .my_non_standard_name
+0000 STSYM .my_non_standard_name_static
 0000 STSYM __ZZ3bariE8bar_init
 0000  GSYM _uninit
 0000 STSYM _sinit
old mode 100644 (file)
new mode 100755 (executable)
index dc4feb4..b1b0e77
@@ -3,16 +3,25 @@
 
 int uninit;
 int init = 1;
+static int custom _asm(".my_non_standard_name") = 1;
 static int suninit;
 static int sinit=0;
+static int scustominit _asm(".my_non_standard_name_static") = 1;
 
 int bar(int x)
 {
        static int bar_uninit;
        static int bar_init=3;
        bar_uninit = x;
+       scustominit = x;
+       custom = x;
        return 20 + suninit + sinit +
                bar_init + bar_uninit + foo(x);
 }
 
+extern void disappear() _asm("lbegone");
+void disappear() {}
+
+extern void foo() _asm(".my_non_standard_function_name");
+void foo() { disappear(); }
 
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 5c34470..1cf9fa0
@@ -35,10 +35,10 @@ all: libfoo.dylib libbar.dylib libbaz.dylib
        ${PASS_IFF_GOOD_MACHO} main
 
 libfoo.dylib : foo.c
-       ${CC} foo.c -dynamiclib -o libfoo.dylib
+       ${CC} ${CCFLAGS} foo.c -dynamiclib -o libfoo.dylib
 
 libbar.dylib : bar.c
-       ${CC} bar.c -dynamiclib -o libbar.dylib -install_name libfoo.dylib
+       ${CC} ${CCFLAGS} bar.c -dynamiclib -o libbar.dylib -install_name libfoo.dylib
 
 libbaz.dylib : libfoo.dylib
        ln -s libfoo.dylib libbaz.dylib
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 89db531..3ccbc85
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
+# Copyright (c) 2005-2007 Apple Inc. All rights reserved.
 #
 # @APPLE_LICENSE_HEADER_START@
 # 
 TESTROOT = ../..
 include ${TESTROOT}/include/common.makefile
 
-# When creating a dylib with the -init option to specify the init  routine in 64-bit,
-# libtool should not complain "file not found: __init".
+#  Verify -init option creates a LC_ROUTINES load command
 
 run: all
 
 all:
-       ${FAIL_IF_ERROR} ${CC} -m64 -c foo.c -o foo_64.o
-       ${FAIL_IF_BAD_OBJ} foo_64.o
-       ${FAIL_IF_ERROR} libtool -dynamic -o libtest.A.dylib foo_64.o \
-               -init __init \
-               -compatibility_version 1 -current_version 1 -install_name "/build/ld64_problem/libtest.A.dylib" \
-               -lSystem
-       ${PASS_IFF_GOOD_MACHO} libtest.A.dylib
+       ${CC}  ${CCFLAGS} foo.c -dynamiclib -o libfoo.dylib -init __init
+       otool -lv libfoo.dylib | grep  LC_ROUTINES | ${FAIL_IF_EMPTY}
+       ${PASS_IFF_GOOD_MACHO} libfoo.dylib
 
 clean:
-       rm -rf *.dylib *.o 
+       rm -rf libfoo.dylib 
diff --git a/unit-tests/test-cases/dylib_init/comment.txt b/unit-tests/test-cases/dylib_init/comment.txt
deleted file mode 100644 (file)
index 9355f2c..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-When creating a dylib with the -init option to specify the init  routine in 64-bit,
-libtool sould not complain "file not found: __init".
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/eh-coalescing-r/Makefile b/unit-tests/test-cases/eh-coalescing-r/Makefile
new file mode 100755 (executable)
index 0000000..ae3b996
--- /dev/null
@@ -0,0 +1,45 @@
+##
+# Copyright (c) 2008 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
+
+
+SHELL = bash # use bash shell so we can redirect just stderr
+
+
+#
+#
+#   <rdar://problem/5726215> comdat warnings in ld -r
+#
+
+run: all
+
+all:
+       ${CXX} ${CCXXFLAGS} foo.cxx -c -o foo.o
+       ${CXX} ${CCXXFLAGS} bar.cxx -c -o bar.o
+       ${LD} -r foo.o bar.o -o foobar.o 2> warnings.log
+       grep warning warnings.log | ${PASS_IFF_EMPTY}
+
+
+clean:
+       rm  foo.o bar.o foobar.o warnings.log
diff --git a/unit-tests/test-cases/eh-coalescing-r/bar.cxx b/unit-tests/test-cases/eh-coalescing-r/bar.cxx
new file mode 100755 (executable)
index 0000000..b48923c
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
+ *
+ * Copyright (c) 2008 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 "func.h"
+
+void bar()
+{
+       func();
+}
+
+
diff --git a/unit-tests/test-cases/eh-coalescing-r/foo.cxx b/unit-tests/test-cases/eh-coalescing-r/foo.cxx
new file mode 100755 (executable)
index 0000000..0a8d99a
--- /dev/null
@@ -0,0 +1,32 @@
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
+ *
+ * Copyright (c) 2008 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 "func.h"
+
+
+void test()
+{
+       func();
+}
diff --git a/unit-tests/test-cases/eh-coalescing-r/func.h b/unit-tests/test-cases/eh-coalescing-r/func.h
new file mode 100755 (executable)
index 0000000..4505225
--- /dev/null
@@ -0,0 +1,35 @@
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
+ *
+ * Copyright (c) 2008 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@
+ */
+
+extern int global;
+extern void foo(int);
+
+
+// this weak func() will have unwind info and a LSDA
+inline int func() 
+{
+       global = 1;
+       return global;
+}
+
diff --git a/unit-tests/test-cases/eh-coalescing/Makefile b/unit-tests/test-cases/eh-coalescing/Makefile
new file mode 100755 (executable)
index 0000000..0c7fb32
--- /dev/null
@@ -0,0 +1,50 @@
+##
+# Copyright (c) 2008 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
+
+#
+# There are two copies of func().  The one from
+# foo.o is weak and has an FDE (.eh) and LSDA.  
+# The one from bar.o is not weak and does not have
+# exception info.  Verify that since linker uses func()
+# from bar.o that it does not use exception info
+# from foo.o
+#
+#  <rdar://problem/5667688> wrong EH information might be used
+#
+
+run: all
+
+all:
+       ${CXX} ${CCXXFLAGS} foo.cxx -c -o foo.o
+       ${CXX} ${CCXXFLAGS} foo2.cxx -c -o foo2.o
+       ${CXX} ${CCXXFLAGS} bar.cxx -c -o bar.o -fno-exceptions
+       ${CXX} ${CCXXFLAGS} -dynamiclib foo.o foo2.o bar.o -o libfoobar.dylib -Wl,-map,libfoobar.map
+       # verify .eh symbol is missing or is from bar.o (file 3)
+       grep '\[  2\] __Z4funcv.eh' libfoobar.map | ${FAIL_IF_STDIN}
+       # verify no LSDA
+       size -l libfoobar.dylib | grep __gcc_except_tab | ${PASS_IFF_EMPTY}
+
+clean:
+       rm  foo.o foo2.o bar.o  libfoobar.map  libfoobar.dylib
diff --git a/unit-tests/test-cases/eh-coalescing/bar.cxx b/unit-tests/test-cases/eh-coalescing/bar.cxx
new file mode 100755 (executable)
index 0000000..83d1845
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
+ *
+ * Copyright (c) 2008 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>
+
+// this non-seak func() will have no unwind info and no LSDA
+int func() { return 0; }
+
+void foo(int x) {}
+
+
diff --git a/unit-tests/test-cases/eh-coalescing/foo.cxx b/unit-tests/test-cases/eh-coalescing/foo.cxx
new file mode 100755 (executable)
index 0000000..ce9939f
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
+ *
+ * Copyright (c) 2008 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 "func.h"
+
+int global;
+
+void test()
+{
+       func();
+}
diff --git a/unit-tests/test-cases/eh-coalescing/foo2.cxx b/unit-tests/test-cases/eh-coalescing/foo2.cxx
new file mode 100755 (executable)
index 0000000..4440aed
--- /dev/null
@@ -0,0 +1,31 @@
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
+ *
+ * Copyright (c) 2008 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 "func.h"
+
+void test2()
+{
+       func();
+}
diff --git a/unit-tests/test-cases/eh-coalescing/func.h b/unit-tests/test-cases/eh-coalescing/func.h
new file mode 100755 (executable)
index 0000000..5bb7c28
--- /dev/null
@@ -0,0 +1,43 @@
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
+ *
+ * Copyright (c) 2008 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@
+ */
+
+extern int global;
+extern void foo(int);
+
+
+// this weak func() will have unwind info and a LSDA
+inline int func() 
+{
+       global = 1;
+       try {
+               foo(1);
+               global = 2;
+       }
+       catch (int x) {
+               foo(2);
+               global = 3;
+       }
+       return global;
+}
+
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/empty-object/Makefile b/unit-tests/test-cases/empty-object/Makefile
new file mode 100755 (executable)
index 0000000..4142b8c
--- /dev/null
@@ -0,0 +1,40 @@
+##
+# Copyright (c) 2007 Apple Computer, 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
+
+#
+# The point of this test is a sanity check that ld
+# can handle an empty (no load commands) .o file
+#
+
+run: all
+
+all:
+       touch empty.s
+       as -arch ${ARCH} -n empty.s -o empty.o
+       ${CC} ${CCFLAGS} main.c empty.o -o main
+       ${PASS_IFF_GOOD_MACHO} main
+
+clean:
+       rm  main empty.s empty.o
diff --git a/unit-tests/test-cases/empty-object/main.c b/unit-tests/test-cases/empty-object/main.c
new file mode 100755 (executable)
index 0000000..76e8197
--- /dev/null
@@ -0,0 +1 @@
+int main() { return 0; }
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/exported-symbols-wildcards-dead_strip/Makefile b/unit-tests/test-cases/exported-symbols-wildcards-dead_strip/Makefile
new file mode 100755 (executable)
index 0000000..cf300a3
--- /dev/null
@@ -0,0 +1,39 @@
+##
+# Copyright (c) 2007 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
+
+#
+# Tests the use of wildcards in exported symbol lists and dead stripping
+#
+
+run: all
+
+all:
+       ${CC} -dynamiclib foo.c -o libfoo.dylib -Wl,-exported_symbol -Wl,'_AB*' -dead_strip
+       nm -j -f libfoo.dylib | grep _good | ${FAIL_IF_EMPTY}
+       nm -j -f libfoo.dylib | grep _bad | ${FAIL_IF_STDIN}
+       ${PASS_IFF_GOOD_MACHO} libfoo.dylib
+       
+clean:
+       rm libfoo.dylib
diff --git a/unit-tests/test-cases/exported-symbols-wildcards-dead_strip/foo.c b/unit-tests/test-cases/exported-symbols-wildcards-dead_strip/foo.c
new file mode 100755 (executable)
index 0000000..6bb8d95
--- /dev/null
@@ -0,0 +1,34 @@
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
+ *
+ * Copyright (c) 2007 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 <stddef.h>
+
+void good() {}
+void bad() {} 
+
+
+void ABC() {}
+void ABD() { good(); }
+void DEF() {}
+void DEG() { bad(); }
+
old mode 100644 (file)
new mode 100755 (executable)
index 1890820..10d1eb1
@@ -30,47 +30,47 @@ include ${TESTROOT}/include/common.makefile
 run: all
 
 all:
-       ${CC} -dynamiclib foo.c -o libfoo.dylib -Wl,-exported_symbol -Wl,'_foo*bar'
+       ${CC} ${CCFLAGS} -dynamiclib foo.c -o libfoo.dylib -Wl,-exported_symbol -Wl,'_foo*bar'
        nm -j -g -f libfoo.dylib | diff - expect1 | ${FAIL_IF_STDIN}
        ${FAIL_IF_BAD_MACHO} libfoo.dylib
 
-       ${CC} -dynamiclib foo.c -o libfoo.dylib -Wl,-exported_symbol -Wl,'_f?o'
+       ${CC} ${CCFLAGS} -dynamiclib foo.c -o libfoo.dylib -Wl,-exported_symbol -Wl,'_f?o'
        nm -j -g -f libfoo.dylib | diff - expect2 | ${FAIL_IF_STDIN}
        ${FAIL_IF_BAD_MACHO} libfoo.dylib
 
-       ${CC} -dynamiclib foo.c -o libfoo.dylib -Wl,-exported_symbol -Wl,'_foo*'
+       ${CC} ${CCFLAGS} -dynamiclib foo.c -o libfoo.dylib -Wl,-exported_symbol -Wl,'_foo*'
        nm -j -g -f libfoo.dylib | diff - expect3 | ${FAIL_IF_STDIN}
        ${FAIL_IF_BAD_MACHO} libfoo.dylib
 
-       ${CC} -dynamiclib foo.c -o libfoo.dylib -Wl,-exported_symbol -Wl,'_f*o*'
+       ${CC} ${CCFLAGS} -dynamiclib foo.c -o libfoo.dylib -Wl,-exported_symbol -Wl,'_f*o*'
        nm -j -g -f libfoo.dylib | diff - expect4 | ${FAIL_IF_STDIN}
        ${FAIL_IF_BAD_MACHO} libfoo.dylib
 
-       ${CC} -dynamiclib foo.c -o libfoo.dylib -Wl,-exported_symbol -Wl,_foo -Wl,-exported_symbol -Wl,'_*bar'
+       ${CC} ${CCFLAGS} -dynamiclib foo.c -o libfoo.dylib -Wl,-exported_symbol -Wl,_foo -Wl,-exported_symbol -Wl,'_*bar'
        nm -j -g -f libfoo.dylib | diff - expect5 | ${FAIL_IF_STDIN}
        ${FAIL_IF_BAD_MACHO} libfoo.dylib
 
-       ${CC} -dynamiclib foo.c -o libfoo.dylib -exported_symbols_list list5
+       ${CC} ${CCFLAGS} -dynamiclib foo.c -o libfoo.dylib -exported_symbols_list list5
        nm -j -g -f libfoo.dylib | diff - expect5 | ${FAIL_IF_STDIN}
        ${FAIL_IF_BAD_MACHO} libfoo.dylib
 
-       ${CC} -dynamiclib foo.c -o libfoo.dylib -Wl,-unexported_symbol -Wl,'_*2*'
+       ${CC} ${CCFLAGS} -dynamiclib foo.c -o libfoo.dylib -Wl,-unexported_symbol -Wl,'_*2*'
        nm -j -g -f libfoo.dylib | diff - expect6 | ${FAIL_IF_STDIN}
        ${FAIL_IF_BAD_MACHO} libfoo.dylib
 
-       ${CC} -dynamiclib foo.c -o libfoo.dylib -Wl,-exported_symbol -Wl,'_f[abcdef]o'
+       ${CC} ${CCFLAGS} -dynamiclib foo.c -o libfoo.dylib -Wl,-exported_symbol -Wl,'_f[abcdef]o'
        nm -j -g -f libfoo.dylib | diff - expect7 | ${FAIL_IF_STDIN}
        ${FAIL_IF_BAD_MACHO} libfoo.dylib
 
-       ${CC} -dynamiclib foo.c -o libfoo.dylib -Wl,-exported_symbol -Wl,'_f[a-f]o'
+       ${CC} ${CCFLAGS} -dynamiclib foo.c -o libfoo.dylib -Wl,-exported_symbol -Wl,'_f[a-f]o'
        nm -j -g -f libfoo.dylib | diff - expect7 | ${FAIL_IF_STDIN}
        ${FAIL_IF_BAD_MACHO} libfoo.dylib
 
-       ${CC} -dynamiclib foo.c -o libfoo.dylib -Wl,-exported_symbol -Wl,'_f[a-z]o'
+       ${CC} ${CCFLAGS} -dynamiclib foo.c -o libfoo.dylib -Wl,-exported_symbol -Wl,'_f[a-z]o'
        nm -j -g -f libfoo.dylib | diff - expect8 | ${FAIL_IF_STDIN}
        ${FAIL_IF_BAD_MACHO} libfoo.dylib
 
-       ${CC} -dynamiclib foo.c -o libfoo.dylib -Wl,-exported_symbol -Wl,'_f[a-fnop]o'
+       ${CC} ${CCFLAGS} -dynamiclib foo.c -o libfoo.dylib -Wl,-exported_symbol -Wl,'_f[a-fnop]o'
        nm -j -g -f libfoo.dylib | diff - expect8 | ${FAIL_IF_STDIN}
        ${PASS_IFF_GOOD_MACHO} libfoo.dylib
        
diff --git a/unit-tests/test-cases/exported_symbols_list-hidden/Makefile b/unit-tests/test-cases/exported_symbols_list-hidden/Makefile
new file mode 100755 (executable)
index 0000000..c27287d
--- /dev/null
@@ -0,0 +1,41 @@
+##
+# Copyright (c) 2007 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
+
+SHELL = bash # use bash shell so we can redirect just stderr
+
+#
+# Verify that -exported_symbols_list of a hidden symbol causes a warning
+#
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} test.c -dynamiclib -exported_symbols_list test.exp -o libtest.dylib 2>warning.log
+       grep _func_hidden1 warning.log | ${FAIL_IF_EMPTY}
+       grep _common_hidden1 warning.log | ${FAIL_IF_EMPTY}
+       ${PASS_IFF_GOOD_MACHO} libtest.dylib
+
+clean:
+       rm -rf libtest.dylib warning.log
diff --git a/unit-tests/test-cases/exported_symbols_list-hidden/test.c b/unit-tests/test-cases/exported_symbols_list-hidden/test.c
new file mode 100755 (executable)
index 0000000..c9fdc35
--- /dev/null
@@ -0,0 +1,18 @@
+
+
+
+static int data_static1 = 1;
+static int data_static2 = 2;
+
+void func_global1() { ++data_static1; }
+void func_global2() { ++data_static2; }
+
+void __attribute__((visibility("hidden"))) func_hidden1() {}
+void __attribute__((visibility("hidden"))) func_hidden2() {}
+
+int common_global1;
+int common_global2;
+
+int __attribute__((visibility("hidden"))) common_hidden1;
+int __attribute__((visibility("hidden"))) common_hidden2;
+
diff --git a/unit-tests/test-cases/exported_symbols_list-hidden/test.exp b/unit-tests/test-cases/exported_symbols_list-hidden/test.exp
new file mode 100755 (executable)
index 0000000..f45858b
--- /dev/null
@@ -0,0 +1,4 @@
+_func_global1
+_func_hidden1
+_common_global1
+_common_hidden1
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index e856b71..3f70e74
@@ -29,6 +29,8 @@ include ${TESTROOT}/include/common.makefile
 
 all: all-${ARCH}
 
+all-armv6: all-true
+
 all-ppc: all-true
 
 all-ppc64: all-true
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index caed2d4..6785960
@@ -37,7 +37,7 @@ all:
        ${FAIL_IF_BAD_OBJ} a-${ARCH}.o
        ${FAIL_IF_ERROR} ar -r libtest-${ARCH}.a test-${ARCH}.o 2>/dev/null
        ${FAIL_IF_ERROR} ranlib libtest-${ARCH}.a
-       ${CC} ${LDFLAGS} a-${ARCH}.o -L. -ltest-${ARCH} -o a-${ARCH}
+       ${CC} ${CCFLAGS} a-${ARCH}.o -L. -ltest-${ARCH} -o a-${ARCH}
        ${PASS_IFF_GOOD_MACHO} a-${ARCH}
 
 clean:
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/implicit_dylib/Makefile b/unit-tests/test-cases/implicit_dylib/Makefile
new file mode 100755 (executable)
index 0000000..c982885
--- /dev/null
@@ -0,0 +1,48 @@
+##
+# Copyright (c) 2007 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
+
+PWD = $(shell pwd)
+
+
+#      Verify -no_implicit_dylibs option 
+#      <rdar://problem/5451987> add option to disable implicit load commands for indirectly used public dylibs
+#
+
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} bar.c -dynamiclib -o libbar.dylib -install_name /usr/lib/libbar.dylib
+       ${CC} ${CCFLAGS} foo.c  -dynamiclib -o libfoo.dylib -reexport_library libbar.dylib -sub_library libbar
+       # verify that main gets bar from libbar
+       ${CC} ${CCFLAGS} main.c libfoo.dylib -o main -L.
+       nm -m main | grep _bar | grep libbar | ${FAIL_IF_EMPTY}
+       # verify that -no_implicit_dylibs causes main to get bar from libfoo
+       ${CC} ${CCFLAGS} main.c libfoo.dylib -o main -Wl,-no_implicit_dylibs -L.
+       nm -m main | grep _bar | grep libfoo | ${FAIL_IF_EMPTY}
+       ${PASS_IFF_GOOD_MACHO} main
+       
+clean:
+       rm -rf libfoo.dylib libbar.dylib main 
diff --git a/unit-tests/test-cases/implicit_dylib/bar.c b/unit-tests/test-cases/implicit_dylib/bar.c
new file mode 100755 (executable)
index 0000000..e2164a2
--- /dev/null
@@ -0,0 +1,7 @@
+
+
+
+void bar()
+{
+}
+
diff --git a/unit-tests/test-cases/implicit_dylib/foo.c b/unit-tests/test-cases/implicit_dylib/foo.c
new file mode 100755 (executable)
index 0000000..1624757
--- /dev/null
@@ -0,0 +1,5 @@
+
+
+void foo()
+{
+}
diff --git a/unit-tests/test-cases/implicit_dylib/main.c b/unit-tests/test-cases/implicit_dylib/main.c
new file mode 100755 (executable)
index 0000000..1f50353
--- /dev/null
@@ -0,0 +1,11 @@
+
+extern void foo();
+extern void bar();
+
+int main()
+{
+       foo();
+       bar();
+       return 0;
+}
+
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 440dd08..e79eb0f
@@ -80,10 +80,25 @@ all:
 
 # build a flat executable that depends on a symbol in the alternate bar to validate that -L is used for indirect dylibs
        ${CC} ${CCFLAGS} -flat_namespace main.c -o main -lfoo -Lhide -L. 
-       ${PASS_IFF_GOOD_MACHO} main
+       ${FAIL_IF_BAD_MACHO} main
+
+
 
+# build Foo.framework that re-exports libbar.dylib embedded in framework
+       mkdir -p Foo.framework
+       ${CC} ${CCFLAGS} -dynamiclib bar.c baz.c -o Foo.framework/libbar.dylib -install_name "`pwd`/Foo.framework/libbar.dylib"
+       ${FAIL_IF_BAD_MACHO} Foo.framework/libbar.dylib
+       ${CC} ${CCFLAGS} -dynamiclib foo.c -o Foo.framework/Foo -F. Foo.framework/libbar.dylib -sub_library libbar
+       ${FAIL_IF_BAD_MACHO} Foo.framework/Foo
 
+# build an alternate libbar.dylib that does not have baz
+       mkdir -p hide
+       ${CC} ${CCFLAGS} -dynamiclib bar.c -o hide/libbar.dylib
+       ${FAIL_IF_BAD_MACHO} hide/libbar.dylib
 
+# build an executable that depends on a symbol not in the alternate libbar.dylib to validate dylibs embedded in frameworks are not searched for
+       ${CC} ${CCFLAGS} main.c -o main -Lhide -F. -framework Foo
+       ${PASS_IFF_GOOD_MACHO} main
 
 
 clean:
diff --git a/unit-tests/test-cases/interposable_list/Makefile b/unit-tests/test-cases/interposable_list/Makefile
new file mode 100755 (executable)
index 0000000..2fe99a8
--- /dev/null
@@ -0,0 +1,47 @@
+##
+# Copyright (c) 2007 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 -interposable and -interposable_list work 
+#
+
+run: all
+
+all:
+       # by default, no test* functions should go through stubs
+       ${CC} ${CCFLAGS} test.c -dynamiclib -o libtest.dylib
+       # -interposable should make all four test* functions go through stubs
+       ${CC} ${CCFLAGS} test.c -dynamiclib -Wl,-interposable -o libtest.dylib
+       otool -Iv libtest.dylib | grep '4 entries' | ${FAIL_IF_EMPTY}
+       otool -Iv libtest.dylib | grep '_test' | ${FAIL_IF_EMPTY}
+       # -interposable_list should make just two test* functions go through stubs
+       ${CC} ${CCFLAGS} test.c -dynamiclib -Wl,-interposable_list test.exp -o libtest.dylib
+       otool -Iv libtest.dylib | grep '2 entries' | ${FAIL_IF_EMPTY}
+       otool -Iv libtest.dylib | grep '_test3' | ${FAIL_IF_STDIN}
+       ${PASS_IFF_GOOD_MACHO} libtest.dylib
+       
+
+clean:
+       rm libtest.dylib
diff --git a/unit-tests/test-cases/interposable_list/test.c b/unit-tests/test-cases/interposable_list/test.c
new file mode 100755 (executable)
index 0000000..937420e
--- /dev/null
@@ -0,0 +1,57 @@
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
+ *
+ * Copyright (c) 2007 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>
+
+const char kMyStr[] = "hello";
+
+int test1()
+{
+       return 10;
+}
+
+int test2()
+{
+       return 10;
+}
+
+int test3()
+{
+       return 10;
+}
+
+int test4()
+{
+       return 10;
+}
+
+const char* getstr()
+{
+       test1();
+       test2();
+       test3();
+       test4();
+       return kMyStr;
+}
+
+
diff --git a/unit-tests/test-cases/interposable_list/test.exp b/unit-tests/test-cases/interposable_list/test.exp
new file mode 100755 (executable)
index 0000000..8f104f1
--- /dev/null
@@ -0,0 +1,2 @@
+_test1
+_test2
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 65de2ef..05d80f1
@@ -16,3 +16,7 @@ _foo: movl  _strcmp, %eax
 _foo:  movl  _strcmp(%rip), %eax
 #endif
 
+#if __arm__
+       ; illegal absolute load
+_foo:  ldr r2, _strcmp
+#endif
diff --git a/unit-tests/test-cases/lazy-dylib-objc/Makefile b/unit-tests/test-cases/lazy-dylib-objc/Makefile
new file mode 100755 (executable)
index 0000000..975ad29
--- /dev/null
@@ -0,0 +1,45 @@
+##
+# Copyright (c) 2008 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
+
+
+SHELL = bash # use bash shell so we can redirect just stderr
+
+
+#
+# Verify that -lazy_library fails if an objc class is referenced
+#
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} foo.m -dynamiclib -o libfoo.dylib -framework Foundation
+       ${FAIL_IF_SUCCESS} ${CC} ${CCFLAGS} main.m -Wl,-lazy_library,libfoo.dylib -o main -framework Foundation 2> fail.log
+       ${CC} ${CCFLAGS} main.m libfoo.dylib -o main -framework Foundation
+       ${PASS_IFF_GOOD_MACHO} main
+       
+       
+       
+clean:
+       rm  libfoo.dylib main rm fail.log
diff --git a/unit-tests/test-cases/lazy-dylib-objc/foo.h b/unit-tests/test-cases/lazy-dylib-objc/foo.h
new file mode 100755 (executable)
index 0000000..eaa591f
--- /dev/null
@@ -0,0 +1,9 @@
+
+#include <Foundation/Foundation.h>
+
+
+@interface Foo : NSObject
+
+
+
+@end
diff --git a/unit-tests/test-cases/lazy-dylib-objc/foo.m b/unit-tests/test-cases/lazy-dylib-objc/foo.m
new file mode 100755 (executable)
index 0000000..35a63b1
--- /dev/null
@@ -0,0 +1,8 @@
+
+#include "foo.h"
+
+@implementation Foo
+
+
+
+@end
diff --git a/unit-tests/test-cases/lazy-dylib-objc/main.m b/unit-tests/test-cases/lazy-dylib-objc/main.m
new file mode 100755 (executable)
index 0000000..0f11f68
--- /dev/null
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "foo.h"
+
+
+int main()
+{
+       [[Foo alloc] init];
+       return 0;
+}
+
diff --git a/unit-tests/test-cases/lazy-dylib/Makefile b/unit-tests/test-cases/lazy-dylib/Makefile
new file mode 100755 (executable)
index 0000000..e3d0d6a
--- /dev/null
@@ -0,0 +1,46 @@
+##
+# Copyright (c) 2008 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
+
+SHELL = bash # use bash shell so we can redirect just stderr
+
+#
+# Verify that -lazy_library works for function calls
+# but fails for data references
+#
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} foo.c -dynamiclib -o libfoo.dylib
+       ${CC} ${CCFLAGS} main.c -Wl,-lazy_library,libfoo.dylib -o main
+       ${FAIL_IF_SUCCESS} ${CC} ${CCFLAGS} bad.c -Wl,-lazy_library,libfoo.dylib -o bad  2> fail.log
+       ${FAIL_IF_SUCCESS} ${CC} ${CCFLAGS} bad2.c -Wl,-lazy_library,libfoo.dylib -o bad2  2> fail.log
+       
+       
+       ${PASS_IFF_GOOD_MACHO} main
+
+clean:
+       rm -f libfoo.dylib main bad bad2 fail.log
+       
diff --git a/unit-tests/test-cases/lazy-dylib/bad.c b/unit-tests/test-cases/lazy-dylib/bad.c
new file mode 100755 (executable)
index 0000000..59a13fb
--- /dev/null
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+
+extern int data;
+
+static int* pd = &data;
+
+int main()
+{
+       return *pd;
+}
diff --git a/unit-tests/test-cases/lazy-dylib/bad2.c b/unit-tests/test-cases/lazy-dylib/bad2.c
new file mode 100755 (executable)
index 0000000..ffd2ce1
--- /dev/null
@@ -0,0 +1,13 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+
+extern int foo();
+
+int main()
+{
+       int (*func)() = foo;
+       if ( func != NULL )
+               (*func)();
+       return 0;
+}
diff --git a/unit-tests/test-cases/lazy-dylib/foo.c b/unit-tests/test-cases/lazy-dylib/foo.c
new file mode 100755 (executable)
index 0000000..c23c9dc
--- /dev/null
@@ -0,0 +1,5 @@
+
+int data = 5;
+
+int foo() { return 1; }
+int bar() { return 1; }
diff --git a/unit-tests/test-cases/lazy-dylib/main.c b/unit-tests/test-cases/lazy-dylib/main.c
new file mode 100755 (executable)
index 0000000..8546854
--- /dev/null
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+
+extern int foo();
+extern int bar();
+
+int main()
+{
+       // two regular external function calls
+       void* x = malloc(16);
+       free(x);
+       // two lazy dylib external function calls
+       int result = foo();
+       fprintf(stderr, "foo() returned %d\n", result);
+       bar();
+       return 0;
+}
old mode 100644 (file)
new mode 100755 (executable)
index b8d4354..6e5febc
  * @APPLE_LICENSE_HEADER_END@
  */
 
+       .literal16
+L01:.long 12345678
+       .long 87654321
+       .long 12345678
+       .long 87654321
+               
+L02:.long 12345678
+       .long 87654321
+       .long 12345678
+       .long 87654322
+
+L03:.long 22345678
+       .long 87654321
+       .long 12345678
+       .long 87654321
+
+L04:.long 12345678
+       .long 87654321
+       .long 12345678
+       .long 87654321
+
+
        .literal8
-       
 L1:    .long 12345678
        .long 87654321
        
old mode 100644 (file)
new mode 100755 (executable)
index 67e2789..42c71e4
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
+# Copyright (c) 2006-2008 Apple Inc. All rights reserved.
 #
 # @APPLE_LICENSE_HEADER_START@
 #
 # @APPLE_LICENSE_HEADER_END@
 ##
 TESTROOT = ../..
+
 include ${TESTROOT}/include/common.makefile
-LLVMGCC = /usr/local/bin/llvm-gcc
-LLVMGXX = /usr/local/bin/llvm-g++
+
+SHELL = bash # use bash shell so we can redirect just stderr
+
+
+LLVMGCC = /Developer/usr/bin/llvm-gcc-4.2 -arch ${ARCH}
+LLVMGXX = /Developer/usr/bin/llvm-g++-4.2 -arch ${ARCH}
+LLVMAR  = /usr/local/bin/llvm-ar
+
 #
 # Test the we set the stack execution bit properly.
 
 run:
-       @if [ -f /usr/local/bin/llvm-gcc ] ; then \
+       if [ -f /Developer/usr/bin/llvm-gcc-4.2 ] ; then \
          $(MAKE) all ; \
        else \
          ${PASS_IFF} /usr/bin/true ; \
        fi
 
-all: zero one two three four five six seven eight nine ten eleven twelve thirteen
+all: zero one two three four five six seven eight nine ten \
+    eleven twelve thirteen fourteen fifteen sixteen seventeen \
+       eighteen nineteen twenty
 
 
 zero:
@@ -44,13 +53,12 @@ zero:
        # MachO : main.c : Ufoo2, Ufoo3
        #
        #echo "Zero..."
-       ${LLVMGCC} ${CCFLAGS} --emit-llvm a.c -c -o a-${ARCH}.o  ${OTHER}
-       ${LLVMGCC} ${CCFLAGS} --emit-llvm b.c -c -o b-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} main.c -c -o main-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} a-${ARCH}.o b-${ARCH}.o main-${ARCH}.o -o main-${ARCH}
-       ${PASS_IFF_GOOD_MACHO} main-${ARCH}
-       ${PASS_IFF} ./main-${ARCH}
-
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm a.c -c -o a.o 
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm b.c -c -o b.o
+       ${LLVMGCC} ${CCFLAGS} main.c -c -o main.o
+       ${LLVMGCC} ${CCFLAGS} a.o b.o main.o -o main.exe
+       ${PASS_IFF_GOOD_MACHO} main.exe
+       
 one:
        #
        # llvm  : a1.c : Dfoo3, Ufoo4
@@ -58,12 +66,11 @@ one:
        # MachO : main1.c : Dfoo4, Ufoo2, Ufoo3
        #
        #echo "One..."
-       ${LLVMGCC} ${CCFLAGS} --emit-llvm a1.c -c -o a1-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} --emit-llvm b1.c -c -o b1-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} main1.c -c -o main1-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} a1-${ARCH}.o b1-${ARCH}.o main1-${ARCH}.o -o main1-${ARCH}
-       ${PASS_IFF_GOOD_MACHO} main1-${ARCH}
-       ${PASS_IFF} ./main1-${ARCH}
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm a1.c -c -o a1.o
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm b1.c -c -o b1.o
+       ${LLVMGCC} ${CCFLAGS} main1.c -c -o main1.o
+       ${LLVMGCC} ${CCFLAGS} a1.o b1.o main1.o -o main1.exe
+       ${PASS_IFF_GOOD_MACHO} main1.exe
 
 two:
        #
@@ -72,12 +79,11 @@ two:
        # MachO : main2.c : Ufoo2, Ufoo3
        #
        #echo "Two..."
-       ${LLVMGCC} ${CCFLAGS} --emit-llvm a2.c -c -o a2-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} --emit-llvm b2.c -c -o b2-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} main2.c -c -o main2-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} a2-${ARCH}.o b2-${ARCH}.o main2-${ARCH}.o -o main2-${ARCH}
-       ${PASS_IFF_GOOD_MACHO} main2-${ARCH}
-       ${PASS_IFF} ./main2-${ARCH}
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm a2.c -c -o a2.o
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm b2.c -c -o b2.o
+       ${LLVMGCC} ${CCFLAGS} main2.c -c -o main2.o
+       ${LLVMGCC} ${CCFLAGS} a2.o b2.o main2.o -o main2.exe
+       ${PASS_IFF_GOOD_MACHO} main2.exe
 
 three:
        #
@@ -86,12 +92,11 @@ three:
        # MachO : main3.c : Ufoo1, Ufoo2, Ubar
        #
        #echo "Three..."
-       ${LLVMGCC} ${CCFLAGS} --emit-llvm a3.c -c -o a3-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} --emit-llvm b3.c -c -o b3-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} main3.c -c -o main3-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} a3-${ARCH}.o b3-${ARCH}.o main3-${ARCH}.o -o main3-${ARCH}
-       ${PASS_IFF_GOOD_MACHO} main3-${ARCH}
-       ${PASS_IFF} ./main3-${ARCH}
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm a3.c -c -o a3.o
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm b3.c -c -o b3.o
+       ${LLVMGCC} ${CCFLAGS} main3.c -c -o main3.o
+       ${LLVMGCC} ${CCFLAGS} a3.o b3.o main3.o -o main3.exe
+       ${PASS_IFF_GOOD_MACHO} main3.exe
 
 four:
        #
@@ -100,12 +105,11 @@ four:
        # MachO : main4.c : Dfoo4, Ufoo2, Ufoo3
        #
        #echo "Four..."
-       ${LLVMGCC} ${CCFLAGS} --emit-llvm a4.c -c -o a4-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} --emit-llvm b4.c -c -o b4-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} main4.c -c -o main4-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} a4-${ARCH}.o b4-${ARCH}.o main4-${ARCH}.o -o main4-${ARCH}
-       ${PASS_IFF_GOOD_MACHO} main4-${ARCH}
-       ${PASS_IFF} ./main4-${ARCH}
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm a4.c -c -o a4.o
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm b4.c -c -o b4.o
+       ${LLVMGCC} ${CCFLAGS} main4.c -c -o main4.o
+       ${LLVMGCC} ${CCFLAGS} a4.o b4.o main4.o -o main4.exe
+       ${PASS_IFF_GOOD_MACHO} main4.exe
 
 five:
        #
@@ -114,26 +118,24 @@ five:
        # MachO : main5.c : Dfoo3, Ufoo1
        #
        #echo "Five..."
-       ${LLVMGCC} ${CCFLAGS} --emit-llvm a5.c -c -o a5-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} --emit-llvm b5.c -c -o b5-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} main5.c -c -o main5-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} a5-${ARCH}.o b5-${ARCH}.o main5-${ARCH}.o -o main5-${ARCH}  -Wl,-dead_strip
-       ${PASS_IFF_GOOD_MACHO} main5-${ARCH}
-       ${PASS_IFF} ./main5-${ARCH}
-       ${OTOOL} -tV main5-${ARCH} | grep foo3 | ${PASS_IFF_EMPTY}
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm a5.c -c -o a5.o
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm b5.c -c -o b5.o
+       ${LLVMGCC} ${CCFLAGS} main5.c -c -o main5.o
+       ${LLVMGCC} ${CCFLAGS} a5.o b5.o main5.o -o main5.exe  -Wl,-dead_strip
+       ${OTOOL} -tV main5.exe | grep foo3 | ${PASS_IFF_EMPTY}
+       ${PASS_IFF_GOOD_MACHO} main5.exe
 
 six:
        #
        # llvm  : a6.c : Dfoo1, Dfoo2
        # MachO : main6.c : Ufoo1
        #
-       #echo "Six..."
-       ${LLVMGCC} ${CCFLAGS} --emit-llvm a6.c -c -o a6-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} main6.c -c -o main6-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} a6-${ARCH}.o  main6-${ARCH}.o -o main6-${ARCH}  -Wl,-dead_strip
-       ${PASS_IFF_GOOD_MACHO} main6-${ARCH}
-       ${PASS_IFF} ./main6-${ARCH}
-       ${OTOOL} -tV main6-${ARCH} | grep foo2 | ${PASS_IFF_EMPTY}
+       #echo "verify dead stripping of foo2 in main executable"
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm a6.c -c -o a6.o
+       ${LLVMGCC} ${CCFLAGS} main6.c -c -o main6.o
+       ${LLVMGCC} ${CCFLAGS} a6.o  main6.o -o main6.exe  -Wl,-dead_strip
+       ${PASS_IFF_GOOD_MACHO} main6.exe
+       ${OTOOL} -tV main6.exe | grep foo2 | ${PASS_IFF_EMPTY}
 
 seven:
        #
@@ -142,12 +144,11 @@ seven:
        # MachO : main7.c : Ufoo1
        #
        #echo "Seven..."
-       ${LLVMGCC} ${CCFLAGS} --emit-llvm a7.c -c -o a7-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} --emit-llvm b7.c -c -o b7-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} main7.c -c -o main7-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} a7-${ARCH}.o b7-${ARCH}.o  main7-${ARCH}.o -o main7-${ARCH}
-       ${PASS_IFF_GOOD_MACHO} main7-${ARCH}
-       ${PASS_IFF} ./main7-${ARCH}
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm a7.c -c -o a7.o
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm b7.c -c -o b7.o
+       ${LLVMGCC} ${CCFLAGS} main7.c -c -o main7.o
+       ${LLVMGCC} ${CCFLAGS} a7.o b7.o  main7.o -o main7.exe
+       ${PASS_IFF_GOOD_MACHO} main7.exe
 
 eight:
        #
@@ -155,12 +156,11 @@ eight:
        # MachO : main8.c : Ufoo1
        #
        #echo "Eight..."
-       ${LLVMGCC} ${CCFLAGS} --emit-llvm a8.c -c -o a8-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} main8.c -c -o main8-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} a8-${ARCH}.o main8-${ARCH}.o -o main8-${ARCH}   -Wl,-dead_strip
-       ${PASS_IFF} ./main8-${ARCH}
-       ${OTOOL} -tV main8-${ARCH} | grep foo2 | ${PASS_IFF_EMPTY}
-       ${OTOOL} -tV main8-${ARCH} | grep unnamed_2_1 | ${PASS_IFF_EMPTY}
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm a8.c -c -o a8.o
+       ${LLVMGCC} ${CCFLAGS} main8.c -c -o main8.o
+       ${LLVMGCC} ${CCFLAGS} a8.o main8.o -o main8.exe   -Wl,-dead_strip
+       ${OTOOL} -tV main8.exe | grep foo2 | ${PASS_IFF_EMPTY}
+       ${OTOOL} -tV main8.exe | grep unnamed_2_1 | ${PASS_IFF_EMPTY}
 
 nine:
        #
@@ -168,13 +168,12 @@ nine:
        # MachO : main9.c : Ufoo1, Dfoo4
        #
        #echo "Nine..."
-       ${LLVMGCC} ${CCFLAGS} --emit-llvm a9.c -c -o a9-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} main9.c -c -o main9-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} a9-${ARCH}.o main9-${ARCH}.o -o main9-${ARCH}   -Wl,-dead_strip
-       ${PASS_IFF} ./main9-${ARCH}
-       ${OTOOL} -tV main9-${ARCH} | grep foo2 | ${PASS_IFF_EMPTY}
-       ${OTOOL} -tV main9-${ARCH} | grep foo4 | ${PASS_IFF_EMPTY}
-       ${OTOOL} -tV main9-${ARCH} | grep unnamed_2_1 | ${PASS_IFF_EMPTY}
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm a9.c -c -o a9.o
+       ${LLVMGCC} ${CCFLAGS} main9.c -c -o main9.o
+       ${LLVMGCC} ${CCFLAGS} a9.o main9.o -o main9.exe   -Wl,-dead_strip
+       ${OTOOL} -tV main9.exe | grep foo2 | ${PASS_IFF_EMPTY}
+       ${OTOOL} -tV main9.exe | grep foo4 | ${PASS_IFF_EMPTY}
+       ${OTOOL} -tV main9.exe | grep unnamed_2_1 | ${PASS_IFF_EMPTY}
 
 ten:
        #
@@ -183,11 +182,11 @@ ten:
        # MachO : main10.c
        #
        #echo "Ten..."
-       ${LLVMGCC} ${CCFLAGS} --emit-llvm a10.c -c -o a10-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} --emit-llvm b10.c -c -o b10-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} main10.c -c -o main10-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} a10-${ARCH}.o b10-${ARCH}.o main10-${ARCH}.o -o main10-${ARCH}
-       ${PASS_IFF_GOOD_MACHO} main10-${ARCH}
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm a10.c -c -o a10.o
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm b10.c -c -o b10.o
+       ${LLVMGCC} ${CCFLAGS} main10.c -c -o main10.o
+       ${LLVMGCC} ${CCFLAGS} a10.o b10.o main10.o -o main10.exe
+       ${PASS_IFF_GOOD_MACHO} main10.exe
 
 eleven:
        #
@@ -195,11 +194,10 @@ eleven:
        # MachO : main11.c
        #
        #echo "Eleven..."
-       ${LLVMGCC} ${CCFLAGS} --emit-llvm a11.c -c -o a11-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} main11.c -c -o main11-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} a11-${ARCH}.o main11-${ARCH}.o -o main11-${ARCH}
-       ${PASS_IFF_GOOD_MACHO} main11-${ARCH}
-       ./main11-${ARCH} >& /dev/null
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm a11.c -c -o a11.o
+       ${LLVMGCC} ${CCFLAGS} main11.c -c -o main11.o
+       ${LLVMGCC} ${CCFLAGS} a11.o main11.o -o main11.exe
+       ${PASS_IFF_GOOD_MACHO} main11.exe
 
 twelve:
        #
@@ -207,11 +205,10 @@ twelve:
        # MachO : main12.c
        #
        #echo "Tweleve..."
-       ${LLVMGCC} ${CCFLAGS} --emit-llvm a12.c -c -o a12-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} main12.c -c -o main12-${ARCH}.o
-       ${LLVMGCC} ${CCFLAGS} a12-${ARCH}.o main12-${ARCH}.o -o main12-${ARCH}
-       ${PASS_IFF_GOOD_MACHO} main12-${ARCH}
-       ./main12-${ARCH}
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm a12.c -c -o a12.o
+       ${LLVMGCC} ${CCFLAGS} main12.c -c -o main12.o
+       ${LLVMGCC} ${CCFLAGS} a12.o main12.o -o main12.exe
+       ${PASS_IFF_GOOD_MACHO} main12.exe
 
 thirteen:
        #
@@ -219,11 +216,74 @@ thirteen:
        # MachO : main13.cc
        #
        # echo "Thirteen..."
-       ${LLVMGCC} ${CXXFLAGS} --emit-llvm a13.cc -c -o a13-${ARCH}.o
-       ${LLVMGCC} ${CXXFLAGS} main13.cc -c -o main13-${ARCH}.o
-       ${LLVMGXX} a13-${ARCH}.o main13-${ARCH}.o -o main13-${ARCH}
-       ${PASS_IFF_GOOD_MACHO} main13-${ARCH}
+       ${LLVMGCC} ${CXXFLAGS} --emit-llvm a13.cc -c -o a13.o
+       ${LLVMGCC} ${CXXFLAGS} main13.cc -c -o main13.o
+       ${LLVMGXX} a13.o main13.o -o main13.exe
 
+fourteen:
+       #
+       # llvm : a14.c b14.c
+       #
+       # echo "verify an used hidden symbol is removed from a dylib"
+       ${LLVMGCC} ${CXXFLAGS} -O4 -dynamiclib a14.c b14.c -o ab14.dylib
+       ${FAIL_IF_BAD_MACHO} ab14.dylib
+       nm -m ab14.dylib | grep _X | ${PASS_IFF_EMPTY}
+
+fifteen:
+       # echo "verify -dead_strip works with hidden symbols"
+       ${LLVMGCC} ${CXXFLAGS} -O4 -Wl,-dead_strip a15.c c15.c -o main15.exe
+       ${LLVMGCC} ${CXXFLAGS} -O4 a15.c c15.c -o main15.exe
+       ${FAIL_IF_BAD_MACHO} main15.exe
+       ${LLVMGCC} ${CXXFLAGS} -O4 -Wl,-dead_strip -dynamiclib a15.c b15.c -o a15.dylib
+       ${LLVMGCC} ${CXXFLAGS} -O4 a15.c b15.c -dynamiclib -o a15.dylib 
+       ${FAIL_IF_BAD_MACHO} a15.dylib
+       
+sixteen:
+       # echo "verify -save-temps"
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm main16.c -c -o main16.o
+       ${LLVMGCC} ${CCFLAGS} main16.o -o main16.exe -Wl,-save-temps
+       ${PASS_IFF} test -e main16.exe.lto.bc
+       ${PASS_IFF} test -e main16.exe.lto.o
+    
+seventeen:
+       # echo "verify ld -r of all bitcode files produces a bitcode file"
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm a17.c -c -o a17.o
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm b17.c -c -o b17.o
+       ${LD} -arch ${ARCH} -r a17.o b17.o -o ab17.o
+       file ab17.o | grep "Mach-O" | ${PASS_IFF_EMPTY}
+       # echo "verify ld -r of bitcode and mach-o produces mach-o"
+       ${LLVMGCC} ${CCFLAGS} b17.c -c -o b17.o
+       ${LD} -arch ${ARCH} -r a17.o b17.o -o ab17.o
+       file ab17.o | grep "Mach-O" | ${PASS_IFF_STDIN}
+
+eighteen:
+       #echo verify ld -r -keep_private_externs works
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm a18.c -c -o a18.o
+       ${LD} -arch ${ARCH} -r -keep_private_externs a18.o -o a18-rkpe.o
+       ObjectDump -nm a18-rkpe.o | grep _common_hidden1 | grep " hidden" | ${FAIL_IF_EMPTY}
+       ObjectDump -nm a18-rkpe.o | grep _func_hidden2 | grep " hidden" | ${FAIL_IF_EMPTY}
+       #echo verify ld -r makes hidden symbols internal (except for commons)
+       ${LD} -arch ${ARCH} -r a18.o -o a18-r.o
+       #ObjectDump -nm a18-r.o | grep _common_hidden1 | grep " hidden" | ${FAIL_IF_EMPTY}
+       #ObjectDump -nm a18-r.o | grep _func_hidden2 | grep " internal" | ${FAIL_IF_EMPTY}
+   
+nineteen:
+       #echo verify missing symbol error
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm main19.c -c -o main19.o
+       ${FAIL_IF_SUCCESS} ${LLVMGCC} ${CCFLAGS} main19.o -o main19.exe 2>fail.log
+       grep _foo fail.log | ${PASS_IFF_STDIN}
+
+twenty:
+       #echo verify bitcode files in archives works 
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm a20.c -c -o a20.o
+       ${LLVMGCC} ${CCFLAGS} --emit-llvm b20.c -c -o b20.o
+       ar cru lib20.a a20.o b20.o
+       ${LLVMGCC} ${CCFLAGS} main20.c lib20.a -all_load -o main20.exe
+       nm main20.exe | grep _foo | ${PASS_IFF_STDIN}
+       
+       
+       
        
 clean:
-       rm -rf *.o main*-* big.*
+       rm -rf *.o main*.exe big.* *.dylib main16.exe.lto.bc fail.log lib20.a
+       
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/llvm-integration/a14.c b/unit-tests/test-cases/llvm-integration/a14.c
new file mode 100755 (executable)
index 0000000..8f4ea09
--- /dev/null
@@ -0,0 +1 @@
+int X __attribute__((visibility("hidden"))) = 14;
diff --git a/unit-tests/test-cases/llvm-integration/a15.c b/unit-tests/test-cases/llvm-integration/a15.c
new file mode 100755 (executable)
index 0000000..a25431b
--- /dev/null
@@ -0,0 +1,3 @@
+void __attribute__((visibility("hidden"))) foo()
+{
+}
diff --git a/unit-tests/test-cases/llvm-integration/a17.c b/unit-tests/test-cases/llvm-integration/a17.c
new file mode 100755 (executable)
index 0000000..3cd06fd
--- /dev/null
@@ -0,0 +1,4 @@
+
+int a = 0;
+int func_a() { return a; }
+
diff --git a/unit-tests/test-cases/llvm-integration/a18.c b/unit-tests/test-cases/llvm-integration/a18.c
new file mode 100755 (executable)
index 0000000..c9fdc35
--- /dev/null
@@ -0,0 +1,18 @@
+
+
+
+static int data_static1 = 1;
+static int data_static2 = 2;
+
+void func_global1() { ++data_static1; }
+void func_global2() { ++data_static2; }
+
+void __attribute__((visibility("hidden"))) func_hidden1() {}
+void __attribute__((visibility("hidden"))) func_hidden2() {}
+
+int common_global1;
+int common_global2;
+
+int __attribute__((visibility("hidden"))) common_hidden1;
+int __attribute__((visibility("hidden"))) common_hidden2;
+
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/llvm-integration/a20.c b/unit-tests/test-cases/llvm-integration/a20.c
new file mode 100755 (executable)
index 0000000..cd52955
--- /dev/null
@@ -0,0 +1,2 @@
+void foo() {}
+void bar() {}
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/llvm-integration/b14.c b/unit-tests/test-cases/llvm-integration/b14.c
new file mode 100755 (executable)
index 0000000..59c5120
--- /dev/null
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int Y;
+extern int X __attribute__((visibility("hidden")));
+void foo() {
+  printf ("%d\n", X); 
+}
diff --git a/unit-tests/test-cases/llvm-integration/b15.c b/unit-tests/test-cases/llvm-integration/b15.c
new file mode 100755 (executable)
index 0000000..13c88d7
--- /dev/null
@@ -0,0 +1,8 @@
+extern void foo();
+void bar() {
+  foo();
+}
+
+void __attribute__((visibility("hidden"))) f2()
+{}
+
diff --git a/unit-tests/test-cases/llvm-integration/b17.c b/unit-tests/test-cases/llvm-integration/b17.c
new file mode 100755 (executable)
index 0000000..47d4cc3
--- /dev/null
@@ -0,0 +1,4 @@
+int b = 0;
+int func_b() { return b; }
+
+
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/llvm-integration/b20.c b/unit-tests/test-cases/llvm-integration/b20.c
new file mode 100755 (executable)
index 0000000..f6c0ed3
--- /dev/null
@@ -0,0 +1 @@
+void frob() {}
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/llvm-integration/c15.c b/unit-tests/test-cases/llvm-integration/c15.c
new file mode 100755 (executable)
index 0000000..0089d64
--- /dev/null
@@ -0,0 +1,9 @@
+extern void foo();
+int main() {
+  foo();
+  return 0;
+}
+
+void __attribute__((visibility("hidden"))) f2()
+{
+}
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/llvm-integration/main16.c b/unit-tests/test-cases/llvm-integration/main16.c
new file mode 100755 (executable)
index 0000000..67112aa
--- /dev/null
@@ -0,0 +1,8 @@
+
+int tent;
+int global = 5;
+
+int foo() { return tent + global; }
+
+int main() { foo(); return 0; }
+
diff --git a/unit-tests/test-cases/llvm-integration/main19.c b/unit-tests/test-cases/llvm-integration/main19.c
new file mode 100755 (executable)
index 0000000..e09c1c9
--- /dev/null
@@ -0,0 +1,8 @@
+extern int foo();
+
+int main()
+{
+       foo();
+       return 0;
+}
+
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/llvm-integration/main20.c b/unit-tests/test-cases/llvm-integration/main20.c
new file mode 100755 (executable)
index 0000000..624e009
--- /dev/null
@@ -0,0 +1,7 @@
+extern void foo();
+
+int main() 
+{
+   foo();
+   return 0;
+}
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index c24abec..5d52553
@@ -31,40 +31,33 @@ run: all
 
 all:
 
-# Test with dwarf-2
-       ${CC} ${CCFLAGS} foo.c -o foo-${ARCH} -gdwarf-2
-       ${FAIL_IF_BAD_MACHO} foo-${ARCH}
-       ${OTOOL} -hlv foo-${ARCH} | grep LC_UUID | ${FAIL_IF_EMPTY}
-       rm -f foo-${ARCH}
-
-# Test with stabs
-       ${CC} ${CCFLAGS} foo.c -o foo-${ARCH} -gfull -gstabs+
-       ${FAIL_IF_BAD_MACHO} foo-${ARCH}
-       ${OTOOL} -hlv foo-${ARCH} | grep LC_UUID | ${FAIL_IF_STDIN}
-
-# Test with two files one with UUID
-       ${CC} ${CCFLAGS} bar.c -c -gdwarf-2
-       ${FAIL_IF_BAD_OBJ} bar.o
-
-       ${LD} -arch ${ARCH} bar.o -r -o bar-${ARCH}.o -no_uuid
-       ${FAIL_IF_BAD_OBJ} bar-${ARCH}.o
-
-       ${CC} ${CCFLAGS} foo.c -c -gdwarf-2
-       ${FAIL_IF_BAD_OBJ} foo.o
-
-       ${LD} -arch ${ARCH} foo.o -r -o foo-${ARCH}.o
-       ${FAIL_IF_BAD_OBJ} foo-${ARCH}.o
-
-       ${CC} ${CCFLAGS} foo-${ARCH}.o bar-${ARCH}.o -o temp-${ARCH}
-       ${FAIL_IF_BAD_MACHO} temp-${ARCH}
-
-       ${OTOOL} -hlv temp-${ARCH} | grep LC_UUID | ${FAIL_IF_EMPTY}
-       rm -f foo.o bar.o foo-${ARCH}.o bar-${ARCH}.o temp-${ARCH}
-
-# Test with with the flag disabling uuid
-       ${CC} ${CCFLAGS} foo.c -o foo-${ARCH} -Wl,-no_uuid -gdwarf-2
-       ${FAIL_IF_BAD_MACHO} foo-${ARCH}
-       ${OTOOL} -hlv foo-${ARCH} | grep LC_UUID | ${PASS_IFF_EMPTY}
+# Test main executable built with dwarf has uuid
+       ${CC} ${CCFLAGS} foo.c -o foo -gdwarf-2
+       ${FAIL_IF_BAD_MACHO} foo
+       ${OTOOL} -hlv foo | grep LC_UUID | ${FAIL_IF_EMPTY}
+       rm -f foo
+
+# Test main executable built with stabs has uuid
+       ${CC} ${CCFLAGS} foo.c -o foo -gfull -gstabs+
+       ${FAIL_IF_BAD_MACHO} foo
+       ${OTOOL} -hlv foo | grep LC_UUID | ${FAIL_IF_EMPTY}
+
+# Test main executable built with dwarf and -no_uuid does not have uuid
+       ${CC} ${CCFLAGS} foo.c -o foo -Wl,-no_uuid -gdwarf-2
+       ${FAIL_IF_BAD_MACHO} foo
+       ${OTOOL} -hlv foo | grep LC_UUID | ${FAIL_IF_STDIN}
+
+# Test ld -r of stabs file has no uuid
+       ${CC} ${CCFLAGS} foo.c -c -o foo.o -gfull -gstabs+
+       ${LD} -arch ${ARCH} foo.o -r -o foo2.o
+       ${OTOOL} -hlv foo2.o | grep LC_UUID | ${FAIL_IF_STDIN}
+
+# Test ld -r of two files one with uuid produces a uuid
+       ${CC} ${CCFLAGS} foo.c -c -o foo.o -gdwarf-2
+       ${LD} -arch ${ARCH} foo.o -r -o foo2.o
+       ${CC} ${CCFLAGS} bar.c -c -gstabs+ -o bar.o
+       ${LD} -arch ${ARCH} -r foo.o bar.o -o foobar.o
+       ${OTOOL} -hlv foobar.o | grep LC_UUID | ${PASS_IFF_STDIN}
 
 clean:
-       rm -rf foo-*
+       rm -rf foo foo.o foo2.o bar.o foobar.o foo.dSYM
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 28f94d6..3c14103
@@ -36,6 +36,8 @@ all-ppc64: hasnl
 
 all-i386: hasnl
 
+all-armv6: hasnl
+
 all-x86_64: all-true
 
 all-true:
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/objc-category-debug-notes/Makefile b/unit-tests/test-cases/objc-category-debug-notes/Makefile
new file mode 100755 (executable)
index 0000000..44023e6
--- /dev/null
@@ -0,0 +1,40 @@
+##
+# Copyright (c) 2008 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 no GSYM for .objc_category_*
+# <rdar://problem/5774231> Linker should not make GSYM debug note for .objc_category_* symbols#
+#
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} test.m -g -o test -framework Foundation
+       nm -ap test | grep GSYM | grep category | ${FAIL_IF_STDIN}
+       ${PASS_IFF_GOOD_MACHO} test
+       
+clean:
+       rm -rf test test.dSYM
diff --git a/unit-tests/test-cases/objc-category-debug-notes/test.m b/unit-tests/test-cases/objc-category-debug-notes/test.m
new file mode 100755 (executable)
index 0000000..3f45e25
--- /dev/null
@@ -0,0 +1,44 @@
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
+ *
+ * Copyright (c) 2008 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 <Foundation/Foundation.h>
+
+
+@interface NSObject (stuff)
+@end
+
+@implementation NSObject (stuff)
+@end
+
+@interface NSObject (other)
+@end
+
+@implementation NSObject (other)
+- (id) init { return self; }
+@end
+
+int main()
+{
+       return 0;
+}
diff --git a/unit-tests/test-cases/objc-exported_symbols_list/Makefile b/unit-tests/test-cases/objc-exported_symbols_list/Makefile
new file mode 100755 (executable)
index 0000000..454a412
--- /dev/null
@@ -0,0 +1,40 @@
+##
+# Copyright (c) 2008 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 ObjC class exports can be suppressed 
+#
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} -dynamiclib foo.m  -framework Foundation -exported_symbols_list foo.exp -o libfoo.dylib
+       nm -m libfoo.dylib | grep Foo | grep ') external' | ${FAIL_IF_EMPTY}
+       nm -m libfoo.dylib | grep Bar | grep non-external | ${FAIL_IF_EMPTY}
+       ${PASS_IFF_GOOD_MACHO} libfoo.dylib
+
+clean:
+       rm -rf *~ libfoo.dylib
diff --git a/unit-tests/test-cases/objc-exported_symbols_list/foo.exp b/unit-tests/test-cases/objc-exported_symbols_list/foo.exp
new file mode 100755 (executable)
index 0000000..720c52d
--- /dev/null
@@ -0,0 +1 @@
+.objc_class_name_Foo
diff --git a/unit-tests/test-cases/objc-exported_symbols_list/foo.m b/unit-tests/test-cases/objc-exported_symbols_list/foo.m
new file mode 100755 (executable)
index 0000000..d39c8f7
--- /dev/null
@@ -0,0 +1,18 @@
+#include <Foundation/Foundation.h>
+
+@interface Foo : NSObject
+@end
+
+@implementation Foo
+@end
+
+
+
+@interface Bar : NSObject
+@end
+
+@implementation Bar
+@end
+
+
+
old mode 100644 (file)
new mode 100755 (executable)
index ed12e39..0abe7d5
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2007 Apple Inc. All rights reserved.
+# Copyright (c) 2007-2008 Apple Inc. All rights reserved.
 #
 # @APPLE_LICENSE_HEADER_START@
 # 
@@ -25,6 +25,8 @@ include ${TESTROOT}/include/common.makefile
 
 SHELL = bash # use bash shell so we can redirect just stderr
 
+
+
 #
 # Validate that the linker catches illegal combinations of .o files 
 # compiled with different GC settings. 
@@ -50,25 +52,32 @@ test:
        ${FAIL_IF_BAD_OBJ} bar-gc-only.o
 
        # check RR + RR -> RR
-       ${CC} foo.o bar.o -dynamiclib -o libfoobar.dylib -framework Foundation
+       ${CC} ${CCFLAGS} foo.o bar.o runtime.c -dynamiclib -o libfoobar.dylib 
        ${FAIL_IF_BAD_MACHO} libfoobar.dylib
 
        # check GC/RR + GC/RR -> GC/RR
-       ${CC} foo-gc.o bar-gc.o -dynamiclib -o libfoobar.dylib -framework Foundation
+       ${CC} ${CCFLAGS} foo-gc.o bar-gc.o runtime.c -dynamiclib -o libfoobar.dylib 
        ${FAIL_IF_BAD_MACHO} libfoobar.dylib
+       otool -o libfoobar.dylib | grep -A4 _image | grep flags | grep 0x2  | ${FAIL_IF_EMPTY}
 
        # check GC + GC -> GC
-       ${CC} foo-gc-only.o bar-gc-only.o -dynamiclib -o libfoobar.dylib -framework Foundation
+       ${CC} ${CCFLAGS} foo-gc-only.o bar-gc-only.o runtime.c -dynamiclib -o libfoobar.dylib 
        ${FAIL_IF_BAD_MACHO} libfoobar.dylib
+       otool -o libfoobar.dylib | grep -A4 _image | grep flags | grep 0x6  | ${FAIL_IF_EMPTY}
 
-       # check RR + GC/RR -> error
-       ${FAIL_IF_SUCCESS} ${CC} foo.o bar-gc.o -dynamiclib -o libfoobar.dylib -framework Foundation 2> fail.log
+       # check RR + GC/RR -> RR
+       ${CC} ${CCFLAGS} foo.o bar-gc.o runtime.c -dynamiclib -o libfoobar.dylib 
+       ${FAIL_IF_BAD_MACHO} libfoobar.dylib
+       otool -o libfoobar.dylib | grep -A4 _image | grep flags | grep 0x[26]  | ${FAIL_IF_STDIN}
+
+       # check GC + GC/RR -> GC
+       ${CC} ${CCFLAGS} foo-gc-only.o bar-gc.o runtime.c -dynamiclib -o libfoobar.dylib  
+       ${FAIL_IF_BAD_MACHO} libfoobar.dylib
+       otool -o libfoobar.dylib | grep -A4 _image | grep flags | grep 0x6  | ${FAIL_IF_EMPTY}
 
        # check RR + GC -> error
-       ${FAIL_IF_SUCCESS} ${CC} foo.o bar-gc-only.o -dynamiclib -o libfoobar.dylib -framework Foundation 2> fail.log
+       ${FAIL_IF_SUCCESS} ${CC} ${CCFLAGS} foo.o bar-gc-only.o runtime.c -dynamiclib -o libfoobar.dylib 2> fail.log
 
-       # check GC + GC/RR -> error
-       ${FAIL_IF_SUCCESS} ${CC} foo-gc-only.o bar-gc.o -dynamiclib -o libfoobar.dylib -framework Foundation 2> fail.log
        ${PASS_IFF} true
 
 clean:
old mode 100644 (file)
new mode 100755 (executable)
index f66df50..5c98709
@@ -1,6 +1,5 @@
-#include <Foundation/Foundation.h>
 
-@interface Bar : NSObject {
+@interface Bar  {
        int f;
 }
 - (void) doit;
old mode 100644 (file)
new mode 100755 (executable)
index 5324bea..e13367e
@@ -1,12 +1,12 @@
-#include <Foundation/Foundation.h>
 
-@interface Foo : NSObject {
+@interface Foo  {
        int f;
 }
 - (void) doit;
 @end
 
+
 @implementation Foo
-- (void) doit { }
+- (void) doit {  }
 @end
 
diff --git a/unit-tests/test-cases/objc-gc-checks/runtime.c b/unit-tests/test-cases/objc-gc-checks/runtime.c
new file mode 100755 (executable)
index 0000000..df4aeef
--- /dev/null
@@ -0,0 +1,2 @@
+void _objc_empty_cache() {}
+void _objc_empty_vtable() {}
diff --git a/unit-tests/test-cases/objc-literal-pointers/Makefile b/unit-tests/test-cases/objc-literal-pointers/Makefile
new file mode 100755 (executable)
index 0000000..9edc357
--- /dev/null
@@ -0,0 +1,47 @@
+##
+# Copyright (c) 2008 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 is unaltered.
+#   <rdar://problem/5680988> __cls_refs section losing S_LITERAL_POINTERS section type
+#
+# note: i386 and ppc objc use some anonymous zerofill that moves and needs to be ignore to compare
+#
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} test.m -c -o test.o
+       ObjectDump  -no_content test.o | grep -v zero-fill-at> test.dump
+
+       ${LD} -arch ${ARCH} -r test.o -o test-r.o
+       ObjectDump  -no_content test-r.o | grep -v zero-fill-at > 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
diff --git a/unit-tests/test-cases/objc-literal-pointers/test.m b/unit-tests/test-cases/objc-literal-pointers/test.m
new file mode 100755 (executable)
index 0000000..a5c1ea8
--- /dev/null
@@ -0,0 +1,33 @@
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
+ *
+ * Copyright (c) 2008 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 <Foundation/Foundation.h>
+
+void test()
+{
+       // two class references
+       // two selector references
+       [NSObject superclass];
+       [NSString description];
+}
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/objc-selector-coalescing/Makefile b/unit-tests/test-cases/objc-selector-coalescing/Makefile
new file mode 100755 (executable)
index 0000000..982f41d
--- /dev/null
@@ -0,0 +1,39 @@
+##
+# Copyright (c) 2008 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 two ObjC translation units that use the same selector
+# link together.
+#
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} main.m other.m -o main -framework Foundation
+       ${PASS_IFF_GOOD_MACHO} main
+       
+clean:
+       rm -rf  main
diff --git a/unit-tests/test-cases/objc-selector-coalescing/main.m b/unit-tests/test-cases/objc-selector-coalescing/main.m
new file mode 100755 (executable)
index 0000000..a266128
--- /dev/null
@@ -0,0 +1,7 @@
+#include <Foundation/Foundation.h>
+
+
+NSString* other()
+{
+       return [NSString stringWithUTF8String:"hello"];
+}
diff --git a/unit-tests/test-cases/objc-selector-coalescing/other.m b/unit-tests/test-cases/objc-selector-coalescing/other.m
new file mode 100755 (executable)
index 0000000..77fd926
--- /dev/null
@@ -0,0 +1,10 @@
+
+#include <Foundation/Foundation.h>
+
+
+int main()
+{
+       [NSString stringWithUTF8String:"hello"];
+       return 0;
+}
+
diff --git a/unit-tests/test-cases/operator-new/Makefile b/unit-tests/test-cases/operator-new/Makefile
new file mode 100755 (executable)
index 0000000..8abf3e1
--- /dev/null
@@ -0,0 +1,40 @@
+##
+# Copyright (c) 2006-2007 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
+
+
+run: all
+
+all: 
+       # 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 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}
+
+
+clean:
+       ${RM} ${RMFLAGS} *~ main  
+
diff --git a/unit-tests/test-cases/operator-new/main.cxx b/unit-tests/test-cases/operator-new/main.cxx
new file mode 100755 (executable)
index 0000000..3c99e35
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2006-2007 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>  // fprintf(), NULL
+#include <stdlib.h> // exit(), EXIT_SUCCESS
+
+#include "test.h" // PASS(), FAIL(), XPASS(), XFAIL()
+
+#include <stdlib.h>
+#include <new>
+
+
+//
+// This test case verifies overriding operator new sets the MH_WEAK_DEFINES bit
+//
+
+#if OP_NEW
+void* operator new(size_t s) throw (std::bad_alloc)
+{
+  return malloc(s);;
+}
+#endif
+
+int main()
+{
+       return 0;
+}
+
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/prebound-main/Makefile b/unit-tests/test-cases/prebound-main/Makefile
new file mode 100755 (executable)
index 0000000..79ef53e
--- /dev/null
@@ -0,0 +1,51 @@
+##
+# Copyright (c) 2006 Apple Computer, 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
+
+SHELL = bash # use bash shell so we can redirect just stderr
+
+#
+# Verify -prebind for 10.3 make ppc prebound and all others not prebound
+#
+
+ifeq (,${findstring 64,$(ARCH)})
+       ifeq (${ARCH},i386)
+               KEYWORD = NOUNDEFS
+       else
+               KEYWORD = PREBOUND
+       endif
+else
+       KEYWORD = NOUNDEFS
+endif
+
+
+run: all
+
+all: 
+       ${CC} ${CCFLAGS} main.c -o main -prebind -mmacosx-version-min=10.3
+       otool -hv main | grep ${KEYWORD} | ${FAIL_IF_EMPTY}
+       ${PASS_IFF_GOOD_MACHO} main
+
+clean:
+       rm main 
diff --git a/unit-tests/test-cases/prebound-main/main.c b/unit-tests/test-cases/prebound-main/main.c
new file mode 100755 (executable)
index 0000000..251979e
--- /dev/null
@@ -0,0 +1,3 @@
+
+int main() { return 0; }
+
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 53d702a..02ed1df
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
+# Copyright (c) 2006-2007 Apple Inc. All rights reserved.
 #
 # @APPLE_LICENSE_HEADER_START@
 #
@@ -24,21 +24,40 @@ TESTROOT = ../..
 include ${TESTROOT}/include/common.makefile
 
 #
-# The point of this test is a sanity check that ld
-# will fail to link a dylib compiled with -mdynamic-no-pic
+# Test that ld can linke a dylib built with -mdynamic-no-pic
 #
 
 
 SHELL = bash # use bash shell so we can redirect just stderr
 
-run:
-       @if [ ${ARCH} = x86_64 ] ; then \
-       ${PASS_IFF} /usr/bin/true ; \
-       else \
-       $(MAKE) all ; \
-       fi
+NO_PIC =  
+STATIC =  
+
+ifeq (${ARCH},i386)
+       NO_PIC =  -mdynamic-no-pic
+       STATIC =  -static
+else 
+       ifeq (${ARCH},ppc)
+               NO_PIC =  -mdynamic-no-pic
+               STATIC =  -mdynamic-no-pic
+       endif
+endif
+
+
+
 all:
-       ${FAIL_IFF} ${CC} ${CCFLAGS} test.c -mdynamic-no-pic -dynamiclib -o test-${ARCH}.dylib 2> fail.log
+       # build libfoo.dylib as regular dylib
+       ${CC} ${CCFLAGS} foo.c -dynamiclib -o libfoo.dylib
+       # build libtest.dylib using -mdynamic-no-pic and -read_only_relocs suppress
+       ${CC} ${CCFLAGS} test.c -c ${NO_PIC}
+       ${CC} ${CCFLAGS} test.o libfoo.dylib -dynamiclib -o libtest.dylib -read_only_relocs suppress -Wl,-w
+       # build libtest.dylib using -static and -read_only_relocs suppress
+       ${CC} ${CCFLAGS} test.c -c ${STATIC}
+       ${CC} ${CCFLAGS} test.o libfoo.dylib -dynamiclib -o libtest.dylib -read_only_relocs suppress -Wl,-w
+       # build main using -static and -read_only_relocs suppress
+       ${CC} ${CCFLAGS} test.c -c ${STATIC}
+       ${CC} ${CCFLAGS} test.o libfoo.dylib -o foo -read_only_relocs suppress -Wl,-w
+       ${PASS_IFF_GOOD_MACHO} foo
 
 clean:
-       rm -rf *.dylib fail.log
+       rm -rf test.o libfoo.dylib libtest.dylib foo
diff --git a/unit-tests/test-cases/read-only-relocs/comment.txt b/unit-tests/test-cases/read-only-relocs/comment.txt
deleted file mode 100644 (file)
index f319d31..0000000
+++ /dev/null
@@ -1 +0,0 @@
-The point of this test is a sanity check that ld will fail to link a dylib compiled with -mdynamic-no-pic
diff --git a/unit-tests/test-cases/read-only-relocs/foo.c b/unit-tests/test-cases/read-only-relocs/foo.c
new file mode 100755 (executable)
index 0000000..bef1580
--- /dev/null
@@ -0,0 +1,6 @@
+
+int b=0;
+
+void func() {}
+
+
old mode 100644 (file)
new mode 100755 (executable)
index f5be7e3..f3484e2
  */
 
 int a=0; 
+extern int b;
+extern void func();
 
-int foo(void
+int main(
 { 
-       return a; 
+       func();
+       return a+b; 
 }
+
old mode 100644 (file)
new mode 100755 (executable)
index 77bdf6b..ba262aa
@@ -32,16 +32,16 @@ include ${TESTROOT}/include/common.makefile
 run: all
 
 all:
-       ${CC} -c foo.c -o foo.${ARCH}.o
+       ${CC} ${CCFLAGS} -c foo.c -o foo.${ARCH}.o
        ${FAIL_IF_BAD_OBJ} foo.${ARCH}.o
 
-       ${CC} -c bar.m -o bar.${ARCH}.o
+       ${CC} ${CCFLAGS} -c bar.m -o bar.${ARCH}.o
        ${FAIL_IF_BAD_OBJ} bar.${ARCH}.o
 
-       ${CC} foo.${ARCH}.o bar.${ARCH}.o -dynamiclib -o libfoo.${ARCH}.dylib -framework Foundation -single_module -mmacosx-version-min=10.5
+       ${CC} ${CCFLAGS} foo.${ARCH}.o bar.${ARCH}.o -dynamiclib -Wl,-no_uuid -o libfoo.${ARCH}.dylib -framework Foundation  -framework CoreFoundation 
        ${FAIL_IF_BAD_MACHO} libfoo.${ARCH}.dylib
 
-       ${CC} foo.${ARCH}.o bar.${ARCH}.o -dynamiclib -o libfoo-alt.${ARCH}.dylib -framework Foundation -single_module -mmacosx-version-min=10.5 -seg1addr 0x12340000 -install_name libfoo.${ARCH}.dylib
+       ${CC} ${CCFLAGS} foo.${ARCH}.o bar.${ARCH}.o -dynamiclib -Wl,-no_uuid -o libfoo-alt.${ARCH}.dylib -framework Foundation -framework CoreFoundation  -seg1addr 0x12340000 -install_name libfoo.${ARCH}.dylib
        ${FAIL_IF_BAD_MACHO} libfoo-alt.${ARCH}.dylib
 
        rebase -arch ${ARCH} -low_address 0x12340000 libfoo.${ARCH}.dylib
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 28cfc56..06e10e8
  * @APPLE_LICENSE_HEADER_END@
  */
 
+#if __arm__
+       .text
+       .align 2
+               
+       .globl _test_loads
+_test_loads:
+    @ PIC load of a
+    ldr r0, L6
+L0:
+    ldr r0, [pc, r0]
+
+    @ PIC load of c
+    ldr r0, L6+4
+L1:
+    ldr r0, [pc, r0]
+
+       @ sorta-absolute load of a
+       ldr r0, L6+8
+       ldr r0, [r0, #0]
+       
+       @ sorta-absolute load of c
+       ldr r0, L6+12
+       ldr r0, [r0, #0]
+
+       @ sorta-absolute load of external
+       ldr r0, L6+16
+       ldr r0, [r0, #0]
+
+       @ PIC load of a + addend ??
+    bx lr
+
+L6:
+    .long _a-(L0+8)
+    .long _c-(L1+8)
+    .long _a
+    .long _c
+    .long _ax
+
+_test_calls:
+       @ call internal
+       bl      _test_branches
+       
+       @ call internal + addend
+       bl      _test_branches+0x19000
+
+       @ call external
+       bl      _external
+       
+       @ call external + addend
+       bl      _external+0x19000
+       
+
+_test_branches:
+       @ call internal
+       bne     _test_calls
+       
+       @ call internal + addend
+       bne     _test_calls+16
+
+       @ call external
+       bne     _external
+       
+       @ call external + addend
+       bne     _external+16
+#endif
+
 #if __ppc__ || __ppc64__
 
        .text
@@ -65,6 +131,14 @@ Lpicbase:
        lis r2,ha16(_a+0x19000)
        lwz r2,lo16(_a+0x19000)(r2)
 
+       ; lea of a + addend
+       lis r2,ha16(_a+0x19000)
+       addi r2,r2,lo16(_a+0x19000)
+
+       ; alt lea of a + addend
+       lis r2,hi16(_a+0x19000)
+       ori r2,r2,lo16(_a+0x19000)
+
        ; absolute load of external + addend
        lis r2,ha16(_ax+0x19000)
        lwz r2,lo16(_ax+0x19000)(r2)
@@ -82,6 +156,14 @@ Lpicbase:
        lis r2,ha16(_a+0x09000)
        lwz r2,lo16(_a+0x09000)(r2)
 
+       ; lea of a + addend
+       lis r2,ha16(_a+0x09000)
+       addi r2,r2,lo16(_a+0x09000)
+
+       ; alt lea of a + addend
+       lis r2,hi16(_a+0x09000)
+       ori r2,r2,lo16(_a+0x09000)
+
        ; absolute load of external + addend
        lis r2,ha16(_ax+0x09000)
        lwz r2,lo16(_ax+0x09000)(r2)
@@ -198,6 +280,15 @@ _pointer_diffs:
 _word_relocs:
        callw   _pointer_diffs
 
+_byte_relocs:
+    mov          $100, %ecx 
+c_1:  
+    loop         c_1
+    mov          $100, %ecx
+c_2:
+    sub          $(1), %ecx
+    jcxz         c_2
+
 #endif
 
 
@@ -273,6 +364,13 @@ _test_branches:
        
        # call external + addend
        jne     _external+16
+       
+_byte_relocs:
+    mov          $100, %ecx 
+c_1:  
+    loop         _byte_relocs
+    nop
+
 #endif
 
 
@@ -345,7 +443,7 @@ _a:
        .long   0
 
 _b:
-#if __ppc__ || __i386__
+#if __ppc__ || __i386__ || __arm__
        .long   _test_calls
        .long   _test_calls+16
        .long   _external
old mode 100644 (file)
new mode 100755 (executable)
index 15a7c35..7428127
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved.
+# Copyright (c) 2005-2008 Apple Computer, Inc. All rights reserved.
 #
 # @APPLE_LICENSE_HEADER_START@
 # 
@@ -32,18 +32,26 @@ include ${TESTROOT}/include/common.makefile
 # No differences means this test passes
 #
 
+ifeq (${ARCH},x86_64)
+       ADDR_SHIFT = 0x1FF000000
+else
+       ADDR_SHIFT = 0xF0000000
+endif
+
+
 run: all
 
 all:
        ${CC} ${CCFLAGS} test.c -c -o test.${ARCH}.o
        ${FAIL_IF_ERROR} ${OBJECTDUMP} -no_content test.${ARCH}.o > test.${ARCH}.o.dump
-       #grep "plus" test.${ARCH}.o.dump | ${FAIL_IF_STDIN}
 
        ${LD} -arch ${ARCH} -r -keep_private_externs test.${ARCH}.o -o test-r.${ARCH}.o
        ${FAIL_IF_ERROR} ${OBJECTDUMP} -no_content test-r.${ARCH}.o > test-r.${ARCH}.o.dump
-       #grep "plus" test-r.${ARCH}.o.dump | ${FAIL_IF_STDIN}
-
-       ${PASS_IFF} diff test.${ARCH}.o.dump test-r.${ARCH}.o.dump
+       ${FAIL_IF_ERROR} diff test.${ARCH}.o.dump test-r.${ARCH}.o.dump
+       
+       ${LD} -arch ${ARCH} -r -keep_private_externs test.${ARCH}.o -seg1addr ${ADDR_SHIFT} -o test2-r.${ARCH}.o
+       ${FAIL_IF_ERROR} ${OBJECTDUMP} -no_content test2-r.${ARCH}.o > test2-r.${ARCH}.o.dump
+       ${PASS_IFF} diff test.${ARCH}.o.dump test2-r.${ARCH}.o.dump
 
 clean:
        rm -rf *.o *.dump
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 1a2991a..767b210
@@ -34,7 +34,6 @@ include ${TESTROOT}/include/common.makefile
 # Currently for ppc64 the .o's alternate! in content
 #
 
-LD=ld64
 
 run: all
 
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 66190ae..e0fa4ad
@@ -22,7 +22,6 @@
 ##
 TESTROOT = ../..
 include ${TESTROOT}/include/common.makefile
-LD=ld64
 
 
 #
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 32c8e81..76b4e95
@@ -29,7 +29,7 @@ include ${TESTROOT}/include/common.makefile
 
 all:
        ${CC} ${CCFLAGS} main.c segKKK.s segJJJ.s segLLL.s -o main
-       nm -j -n main | grep _sym > symbol.order
+       nm -j -n main | grep _sym_ > symbol.order
        ${FAIL_IF_ERROR} diff symbol.order expected.order
        ${PASS_IFF_GOOD_MACHO} main
        
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/slow-x86-stubs/Makefile b/unit-tests/test-cases/slow-x86-stubs/Makefile
new file mode 100755 (executable)
index 0000000..ee6a0e5
--- /dev/null
@@ -0,0 +1,42 @@
+##
+# Copyright (c) 2007 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
+
+#
+# Sanity check that -slow_stubs for i386 leaves no __IMPORT segment
+#
+
+run: all
+
+
+
+all:
+       ${CC} ${CCFLAGS} hello.c -o hello -Wl,-slow_stubs
+       size -l hello | grep __IMPORT | ${FAIL_IF_STDIN} 
+       ${CC} ${CCFLAGS} hello.c -dynamiclib -o libhello.dylib -Wl,-slow_stubs
+       size -l libhello.dylib | grep __IMPORT | ${FAIL_IF_STDIN}
+       ${PASS_IFF_GOOD_MACHO} hello
+
+clean:
+       rm  hello libhello.dylib
diff --git a/unit-tests/test-cases/slow-x86-stubs/hello.c b/unit-tests/test-cases/slow-x86-stubs/hello.c
new file mode 100755 (executable)
index 0000000..fe3b0df
--- /dev/null
@@ -0,0 +1,7 @@
+#include <stdio.h>
+
+int main()
+{
+       fprintf(stdout, "hello\n");
+       return 0;
+}
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 49e6467..670f014
 TESTROOT = ../..
 include ${TESTROOT}/include/common.makefile
 
-# Test the ld commands -stack_addr, -stack_size
-# Test using both -stack_add and -stack_size
+# Test the ld option -stack_addr and -stack_size used together
 
+ifeq ($(ARCH),armv6)
+       STACK_ADDR = 0x2C000000
+       STACK_SIZE = 0x05000000
+       STACK_TOP  = 0x27000000
+else
 ifeq (,${findstring 64,$(ARCH)})
        STACK_ADDR = 0xCC000000
        STACK_SIZE = 0x05000000
@@ -35,37 +39,19 @@ else
        STACK_TOP  = 0x000000010b000000
        STACK_SIZE = 0x0000000005000000
 endif
-
+endif
 
 run: all
 
 
 
 all:
-# info seems to not work, use warning:
-       ${CC} ${CCFLAGS} -c main.c -o main-${ARCH}.o
-       ${FAIL_IF_BAD_OBJ} main-${ARCH}.o
-
-       ${LD} -arch ${ARCH} \
-               -stack_addr ${STACK_ADDR} -stack_size ${STACK_SIZE} \
-               -lcrt1.o -lSystem \
-               main-${ARCH}.o -o main \
-# # Can check warning if desired.
-#              > lderr.out
-#ifeq (,${findstring 64,$(ARCH)})
-#      grep "warning no -stack_size specified using the default size" lderr.out | ${FAIL_IF_EMPTY}
-#else
-#      grep "failed: -stack_addr must be used with -stack_size" lderr.out | ${FAIL_IF_EMPTY}
-#endif
-
-# Check for __UNIXSTACK section in object, check that it has the correct value
-       ${FAIL_IF_ERROR} ${OTOOL} -l main>ldcmds.out
-       (echo '1,/^[ ]*segname __UNIXSTACK$$/-d'; echo '/^[ ]*segname /,$$d'; echo w; echo q) | ed ldcmds.out >/dev/null
-       grep __UNIXSTACK ldcmds.out | ${FAIL_IF_EMPTY}
-       grep " vmaddr[ ]*${STACK_TOP}" ldcmds.out | ${FAIL_IF_EMPTY}
-       grep " vmsize[ ]*${STACK_SIZE}" ldcmds.out | ${FAIL_IF_EMPTY}
-
+       ${CC} ${CCFLAGS} main.c -o main -Wl,-stack_size,${STACK_SIZE} -Wl,-stack_addr,${STACK_ADDR}
+       # Check for __UNIXSTACK section in object, check that it has the correct value
+       otool -l main | grep -A6 __UNIXSTACK > main.otool
+       grep " vmsize[ ]*${STACK_SIZE}" main.otool | ${FAIL_IF_EMPTY}
+       grep " vmaddr[ ]*${STACK_TOP}" main.otool | ${FAIL_IF_EMPTY}
        ${PASS_IFF_GOOD_MACHO} main
 
 clean:
-       rm -rf *.o *.err *.out main
+       rm -rf main main.otool
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index a13d767..6134c7e
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
+# Copyright (c) 2005-2008 Apple Inc. All rights reserved.
 #
 # @APPLE_LICENSE_HEADER_START@
 # 
 TESTROOT = ../..
 include ${TESTROOT}/include/common.makefile
 
-# Test the ld commands -stack_addr, -stack_size
-# Test using -stack_size only
+# Test the ld option -stack_size adds a custom stack segment
 
+ifeq ($(ARCH),armv6)
+       STACK_ADDR = 0x30000000
+       STACK_SIZE = 0x05000000
+       STACK_TOP  = 0x2b000000
+else
 ifeq (,${findstring 64,$(ARCH)})
        STACK_ADDR = 0xC0000000
        STACK_SIZE = 0x05000000
        STACK_TOP  = 0xbb000000
 else
-#ifeq (${ARCH},x86_64)
        STACK_ADDR = 0x0007fff5fc000000
        STACK_TOP  = 0x00007fff57000000
        STACK_SIZE = 0x0000000005000000
-#else
-       #STACK_ADDR = 0x0007ffff00000000
-       #STACK_TOP  = 0x0007fffefb000000
-       #STACK_SIZE = 0x0000000005000000
-#endif
+endif
 endif
 
 
 run: all
 
-
-
 all:
-# info seems to not work, use warning:
-       ${CC} ${CCFLAGS} -c main.c -o main-${ARCH}.o
-       ${FAIL_IF_BAD_OBJ} main-${ARCH}.o
-
-
-       ${LD} -arch ${ARCH} \
-               -stack_size ${STACK_SIZE} \
-               -lcrt1.o -lSystem \
-               main-${ARCH}.o -o main \
-               2>lderr.out
-
-# Can check warning if desired.
-#ifeq (,${findstring 64,$(ARCH)})
-#      grep "warning no -stack_size specified using the default size" lderr.out | ${FAIL_IF_EMPTY}
-#else
-#      grep "failed: -stack_addr must be used with -stack_size" lderr.out | ${FAIL_IF_EMPTY}
-#endif
-
-# Check for __UNIXSTACK section in object, check that it has the correct value
-       ${FAIL_IF_ERROR} ${OTOOL} -l main>ldcmds.out
-       (echo '1,/^[ ]*segname __UNIXSTACK$$/-d'; echo '/^[ ]*segname /,$$d'; echo w; echo q) | ed ldcmds.out >/dev/null
-       grep __UNIXSTACK ldcmds.out | ${FAIL_IF_EMPTY}
-       grep " vmsize[ ]*${STACK_SIZE}" ldcmds.out | ${FAIL_IF_EMPTY}
-       grep " vmaddr[ ]*${STACK_TOP}" ldcmds.out | ${FAIL_IF_EMPTY}
+       ${CC} ${CCFLAGS} main.c -o main -Wl,-stack_size,${STACK_SIZE}
+       # Check for __UNIXSTACK section in object, check that it has the correct value
+       otool -l main | grep -A6 __UNIXSTACK > main.otool
+       grep " vmsize[ ]*${STACK_SIZE}" main.otool | ${FAIL_IF_EMPTY}
+       grep " vmaddr[ ]*${STACK_TOP}" main.otool | ${FAIL_IF_EMPTY}
        ${PASS_IFF_GOOD_MACHO} main
 
 clean:
-       rm -rf *.o *.err *.out main
+       rm -rf main main.otool
old mode 100644 (file)
new mode 100755 (executable)
index 5c73586..4aaef3a
@@ -1,6 +1,6 @@
 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
  *
- * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2006-2008 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  */
 #include <stdio.h>
 
+#if __x86_64__
+static char buffer[8000000000];
+#elif __arm__
+static char buffer[100000000];
+#else
+static char buffer[2000000000];
+#endif
+
 int main()
 {
-       return 0;
+       return buffer[0];
 }
old mode 100644 (file)
new mode 100755 (executable)
index 8e14133..2d71eff
@@ -24,20 +24,12 @@ TESTROOT = ../..
 include ${TESTROOT}/include/common.makefile
 
 #
-# The point of this test is a sanity check that ld
-# can link a static executable (requires non-public archives)
+# Test that ld can link a static executable
 #
 
-run:
-       @if [ ${ARCH} = ppc ] || [ ${ARCH} = i386 ] ; then \
-       $(MAKE) all ; \
-       else \
-       $(PASS_IFF) /usr/bin/true ; \
-       fi
-
 all:
-       ${CC} ${CCFLAGS} test.c -static -o test-${ARCH} -L/usr/local/lib/system -lc_static -lm_static -dead_strip 2>/dev/null
-       ${PASS_IFF_GOOD_MACHO} test-${ARCH}
+       ${CC} ${CCFLAGS} test.c -static -o test -e _entry -nostdlib -Wl,-new_linker
+       ${PASS_IFF_GOOD_MACHO} test
 
 clean:
-       rm -rf test-*
+       rm -rf test
diff --git a/unit-tests/test-cases/static-executable/comment.txt b/unit-tests/test-cases/static-executable/comment.txt
deleted file mode 100644 (file)
index bc535a3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-The point of this test is a sanity check that ld can link a static executable (requires non-public archives)
old mode 100644 (file)
new mode 100755 (executable)
index ab472fb..27fe88d
@@ -1,28 +1,11 @@
-/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
- *
- * Copyright (c) 2006 Apple Computer, 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@
- */
 
-int main()
+int foo()
 {
        return 0;
 }
+
+
+int entry()
+{
+       return foo();
+}
old mode 100644 (file)
new mode 100755 (executable)
index 343855e..323200e
@@ -31,7 +31,7 @@ include ${TESTROOT}/include/common.makefile
 run: all
 
 all:
-       ${FAIL_IF_ERROR} ${CC} ${CCFLAGS} test.c -static -o test-${ARCH} -L/usr/local/lib/system -lc_static -lm_static
+       ${FAIL_IF_ERROR} ${CC} ${CCFLAGS} test.c -static -o test-${ARCH} -L/usr/local/lib/system -lc_static -lm_static -Wl,-new_linker
        ${FAIL_IF_BAD_MACHO} test-${ARCH}
        ${FAIL_IF_ERROR} strip test-${ARCH}
        ${PASS_IFF_GOOD_MACHO} test-${ARCH}
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/stub-generation-weak/Makefile b/unit-tests/test-cases/stub-generation-weak/Makefile
new file mode 100755 (executable)
index 0000000..e7cf05c
--- /dev/null
@@ -0,0 +1,42 @@
+##
+# Copyright (c) 2007 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 ld generates correct stubs when some are weak_import
+#
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} foo.c -dynamiclib -o libfoo.dylib
+       ${CC} ${CCFLAGS} main.c libfoo.dylib -o main
+       otool -Iv main | grep '_foo' | ${FAIL_IF_EMPTY}
+       otool -Iv main | grep '_bar' | ${FAIL_IF_EMPTY}
+       otool -Iv main | grep '_baz' | ${FAIL_IF_EMPTY}
+       ${PASS_IFF_GOOD_MACHO} main
+       
+
+clean:
+       rm libfoo.dylib main
diff --git a/unit-tests/test-cases/stub-generation-weak/foo.c b/unit-tests/test-cases/stub-generation-weak/foo.c
new file mode 100755 (executable)
index 0000000..0122e53
--- /dev/null
@@ -0,0 +1,5 @@
+
+void foo() {}
+void bar() {}
+void baz() {}
+
diff --git a/unit-tests/test-cases/stub-generation-weak/main.c b/unit-tests/test-cases/stub-generation-weak/main.c
new file mode 100755 (executable)
index 0000000..1803c6a
--- /dev/null
@@ -0,0 +1,40 @@
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
+ *
+ * Copyright (c) 2007 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>
+
+extern void foo() __attribute__((weak_import));
+extern void bar() __attribute__((weak_import));
+extern void baz();
+
+int main()
+{
+       if ( &foo != 0 ) {
+               foo();
+               bar();
+       }
+       baz();
+       return 0;
+}
+
+
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/tentative-and-archive/Makefile b/unit-tests/test-cases/tentative-and-archive/Makefile
new file mode 100755 (executable)
index 0000000..e8a4a0e
--- /dev/null
@@ -0,0 +1,50 @@
+##
+# Copyright (c) 2008 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
+
+SHELL = bash # use bash shell so we can redirect just stderr
+
+
+#
+# Test how tentative definitions interact with archives
+# main.c has a tenative definition for _var which 
+# should *not* cause libfoo.a(foo.o) to be loaded.
+#
+# <rdar://problem/5779681> ld crashes building XsanFS
+# <rdar://problem/5852023> -undefined dynamic_lookup causes spurious extra symbols
+#
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} foo.c -c -o foo.o
+       libtool -static foo.o -o libfoo.a
+       ${CC} ${CCFLAGS} main.c libfoo.a -o main
+       ${CC} ${CCFLAGS} main.c libfoo.a -o main -undefined dynamic_lookup
+       nm -m main | grep "looked up" | ${FAIL_IF_STDIN}
+       ${PASS_IFF_GOOD_MACHO} main
+               
+
+clean:
+       rm -rf main libfoo.a foo.o
diff --git a/unit-tests/test-cases/tentative-and-archive/foo.c b/unit-tests/test-cases/tentative-and-archive/foo.c
new file mode 100755 (executable)
index 0000000..a2254b5
--- /dev/null
@@ -0,0 +1,6 @@
+
+extern void bar();
+
+void foo() { bar(); }
+
+int var = 9;
diff --git a/unit-tests/test-cases/tentative-and-archive/main.c b/unit-tests/test-cases/tentative-and-archive/main.c
new file mode 100755 (executable)
index 0000000..e5046a0
--- /dev/null
@@ -0,0 +1,8 @@
+
+int var;
+
+int main()
+{
+       var = 3;
+       return 0;
+}
diff --git a/unit-tests/test-cases/tentative-and-dylib/Makefile b/unit-tests/test-cases/tentative-and-dylib/Makefile
new file mode 100755 (executable)
index 0000000..0ed1fa4
--- /dev/null
@@ -0,0 +1,56 @@
+##
+# Copyright (c) 2007 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
+
+SHELL = bash # use bash shell so we can redirect just stderr
+
+
+#
+# Test how tentative definitions interact with dylibs
+#
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} bar.c -dynamiclib -o libbar.dylib
+       ${CC} ${CCFLAGS} foo.c -dynamiclib -o libfoo.dylib -Wl,-reexport_library,libbar.dylib
+       # verify -warn_commons works
+       ${CC} ${CCFLAGS} main.c libfoo.dylib -o main -Wl,-warn_commons 2> warnings.log
+       grep "using common symbol" warnings.log | ${FAIL_IF_EMPTY}
+       # verify -commons use_dylibs works
+       ${CC} ${CCFLAGS} main.c libfoo.dylib -o main -Wl,-commons,use_dylibs 
+       nm -m main | grep _var | grep libfoo | ${FAIL_IF_EMPTY}
+       # verify -commons ignore_dylibs works
+       ${CC} ${CCFLAGS} main.c libfoo.dylib -o main -Wl,-commons,ignore_dylibs 
+       nm -m main | grep _var | grep __DATA | ${FAIL_IF_EMPTY}
+       # verify -commons error works
+        ${FAIL_IF_SUCCESS} ${CC} ${CCFLAGS} main.c libfoo.dylib -o main -Wl,-commons,error  2> warnings.log
+       # verify -commons use_dylibs works with indirect dylibs
+       ${CC} ${CCFLAGS} main.c  -Dvar=bar libfoo.dylib -o main -Wl,-commons,use_dylibs 
+       nm -m main | grep _bar | grep libfoo | ${FAIL_IF_EMPTY}
+       ${PASS_IFF_GOOD_MACHO} main
+               
+
+clean:
+       rm -rf main libfoo.dylib libbar.dylib warnings.log
diff --git a/unit-tests/test-cases/tentative-and-dylib/bar.c b/unit-tests/test-cases/tentative-and-dylib/bar.c
new file mode 100755 (executable)
index 0000000..e425999
--- /dev/null
@@ -0,0 +1 @@
+void bar() {}
diff --git a/unit-tests/test-cases/tentative-and-dylib/foo.c b/unit-tests/test-cases/tentative-and-dylib/foo.c
new file mode 100755 (executable)
index 0000000..c1bb919
--- /dev/null
@@ -0,0 +1,2 @@
+void foo() {}
+int var = 9;
diff --git a/unit-tests/test-cases/tentative-and-dylib/main.c b/unit-tests/test-cases/tentative-and-dylib/main.c
new file mode 100755 (executable)
index 0000000..e5046a0
--- /dev/null
@@ -0,0 +1,8 @@
+
+int var;
+
+int main()
+{
+       var = 3;
+       return 0;
+}
diff --git a/unit-tests/test-cases/tentative-to-real-hidden/Makefile b/unit-tests/test-cases/tentative-to-real-hidden/Makefile
new file mode 100755 (executable)
index 0000000..833d676
--- /dev/null
@@ -0,0 +1,52 @@
+##
+# Copyright (c) 2007 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 that -r -d -exported_symbol_list uses proper relocations for hidden 
+# newly defined (no longer tentative) definitions.
+#
+
+ifneq (${ARCH},x86_64)
+       BETTER_NOT_FIND = _tent
+else
+       # x86_64 uses a different style of relocations, so external relocs are ok to have
+       BETTER_NOT_FIND = blahblah
+endif
+
+
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} test.c -c -o test.o
+       ${FAIL_IF_BAD_OBJ} test.o
+
+       ${LD} -arch ${ARCH} -d -r test.o -exported_symbol _tent1 -o test-r.o
+       otool -rv test-r.o | grep ${BETTER_NOT_FIND} | ${PASS_IFF_EMPTY}
+       
+
+clean:
+       rm -rf *.o
diff --git a/unit-tests/test-cases/tentative-to-real-hidden/test.c b/unit-tests/test-cases/tentative-to-real-hidden/test.c
new file mode 100755 (executable)
index 0000000..c9cf479
--- /dev/null
@@ -0,0 +1,11 @@
+
+// tentative definitions
+int tent1;
+int tent2;
+int  __attribute__((visibility("hidden"))) tent3;
+
+// initialized to point to tentative definitions
+int* pa = &tent1;
+int* pb = &tent2;
+int* pc = &tent3;
+
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/thumb-blx/Makefile b/unit-tests/test-cases/thumb-blx/Makefile
new file mode 100755 (executable)
index 0000000..65b3131
--- /dev/null
@@ -0,0 +1,54 @@
+##
+# Copyright (c) 2007 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 the linker parses call sites correctly.
+# The tricky case is thumb, which uses a blx to call to
+# the arm stubs.  This test verifies that there is no
+# +2 error by checking for "plus" and that when the file
+# is regenerated through ld -r that the dumped output
+# remains unchanged.
+#
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} test.c -c -o test.o
+       ${FAIL_IF_ERROR} ${OBJECTDUMP} -no_content test.o > test.o.dump
+       # verify no +2 errors
+       grep "plus" test.o.dump | ${FAIL_IF_STDIN}
+       # verify .o file can be regenerated to an equivalent state
+       ${LD} -arch ${ARCH} -r -keep_private_externs test.o -o test-r.o
+       ${FAIL_IF_ERROR} ${OBJECTDUMP} -no_content test-r.o > test-r.o.dump
+       # verify final linked image has no +2 errors
+       ${CC} ${CCFLAGS} test.o -o test
+       otool -tV -p _main test | grep blx | grep -v _malloc | ${FAIL_IF_STDIN}
+       ${CC} ${CCFLAGS} test-r.o -o test-r
+       otool -tV -p _main test-r | grep blx | grep -v _malloc | ${FAIL_IF_STDIN}
+       ${PASS_IFF} diff test.o.dump test-r.o.dump 
+
+clean:
+       rm -rf test.o test-r.o test.o.dump test-r.o.dump test test-r
diff --git a/unit-tests/test-cases/thumb-blx/test.c b/unit-tests/test-cases/thumb-blx/test.c
new file mode 100755 (executable)
index 0000000..ce0359f
--- /dev/null
@@ -0,0 +1,36 @@
+/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
+ *
+ * Copyright (c) 2007 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 <stdlib.h>
+
+int main()
+{
+       malloc(1);
+       malloc(2);
+       malloc(3);
+       malloc(4);
+       return 0;
+}
+
+
diff --git a/unit-tests/test-cases/visibility-warning-dylib-v-archive/Makefile b/unit-tests/test-cases/visibility-warning-dylib-v-archive/Makefile
new file mode 100755 (executable)
index 0000000..789a304
--- /dev/null
@@ -0,0 +1,46 @@
+##
+# Copyright (c) 2007 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 late loaded hidden symbol from an archive does not conflict
+# with a symbol previously found in a dylib.
+# <rdar://problem/5342320> gcc 4.2: DejaGnu failures due to libgcc visibility issues with -m64 -mmacosx-version-min=10.4 (G5)
+#
+
+SHELL = bash # use bash shell so we can redirect just stderr
+
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} foo.c -dynamiclib -o libfoo.dylib
+       ${CC} ${CCFLAGS} -c bar.c -o bar.o
+       libtool -static bar.o -o libbar.a
+       ${CC} ${CCFLAGS} main.c -o main libfoo.dylib libbar.a 2>warning.log
+       cat warning.log | ${PASS_IFF_EMPTY}
+       
+
+clean:
+       rm -f libfoo.dylib bar.o libbar.a main warning.log
diff --git a/unit-tests/test-cases/visibility-warning-dylib-v-archive/bar.c b/unit-tests/test-cases/visibility-warning-dylib-v-archive/bar.c
new file mode 100755 (executable)
index 0000000..276f502
--- /dev/null
@@ -0,0 +1,11 @@
+
+
+void __attribute__((weak,visibility("hidden"))) foo()
+{
+
+}
+
+
+void bar()
+{
+}
diff --git a/unit-tests/test-cases/visibility-warning-dylib-v-archive/foo.c b/unit-tests/test-cases/visibility-warning-dylib-v-archive/foo.c
new file mode 100755 (executable)
index 0000000..3d8616a
--- /dev/null
@@ -0,0 +1,5 @@
+
+
+void __attribute__((weak)) foo()
+{
+}
diff --git a/unit-tests/test-cases/visibility-warning-dylib-v-archive/main.c b/unit-tests/test-cases/visibility-warning-dylib-v-archive/main.c
new file mode 100755 (executable)
index 0000000..8c9c95c
--- /dev/null
@@ -0,0 +1,11 @@
+
+extern void foo();
+extern void bar();
+
+
+int main()
+{
+       foo();
+       bar();
+       return 0;
+}
diff --git a/unit-tests/test-cases/visibility-warning/Makefile b/unit-tests/test-cases/visibility-warning/Makefile
new file mode 100755 (executable)
index 0000000..43bdcd8
--- /dev/null
@@ -0,0 +1,57 @@
+##
+# Copyright (c) 2007 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 two weak symbols with different visibility causes a warning
+# and a weak and strong with different visibilities do not cause a warning.
+# <rdar://problem/5459546> Spurious link warnings for inline members of C++ template classes
+#
+
+SHELL = bash # use bash shell so we can redirect just stderr
+
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} -c foo_weak_hidden.c -o foo_weak_hidden.o
+       ${CC} ${CCFLAGS} -c foo_weak.c -o foo_weak.o
+       ${CC} ${CCFLAGS} -c foo.c -o foo.o
+       ${CC} ${CCFLAGS} -c foo_hidden.c -o foo_hidden.o
+       # weak default and weak hidden should warn
+       ${CC} ${CCFLAGS} foo_weak_hidden.o foo_weak.o -dynamiclib -o libfoo.dylib 2> warnings.log
+       grep visibility warnings.log | ${FAIL_IF_EMPTY}
+       # weak hidden and strong should not warn
+       ${CC} ${CCFLAGS} foo_weak_hidden.o foo.o -dynamiclib -o libfoo.dylib  2> warnings.log
+       grep visibility warnings.log | ${FAIL_IF_STDIN}
+       # weak default and strong hidden should not warn
+       ${CC} ${CCFLAGS} foo_weak.o foo_hidden.o -dynamiclib -o libfoo.dylib  2> warnings.log
+       grep visibility warnings.log | ${FAIL_IF_STDIN}
+       # weak default and weak hidden but -w should not warn
+       ${CC} ${CCFLAGS} foo_weak_hidden.o foo_weak.o -dynamiclib -w -o libfoo.dylib 2> warnings.log
+       cat warnings.log | ${FAIL_IF_STDIN}
+       ${PASS_IFF_GOOD_MACHO} libfoo.dylib
+
+clean:
+       rm  libfoo.dylib foo_weak_hidden.o foo_weak.o foo.o foo_hidden.o warnings.log
diff --git a/unit-tests/test-cases/visibility-warning/foo.c b/unit-tests/test-cases/visibility-warning/foo.c
new file mode 100755 (executable)
index 0000000..1624757
--- /dev/null
@@ -0,0 +1,5 @@
+
+
+void foo()
+{
+}
diff --git a/unit-tests/test-cases/visibility-warning/foo_hidden.c b/unit-tests/test-cases/visibility-warning/foo_hidden.c
new file mode 100755 (executable)
index 0000000..cac53ce
--- /dev/null
@@ -0,0 +1,5 @@
+
+
+void __attribute__((visibility("hidden"))) foo()
+{
+}
diff --git a/unit-tests/test-cases/visibility-warning/foo_weak.c b/unit-tests/test-cases/visibility-warning/foo_weak.c
new file mode 100755 (executable)
index 0000000..3d8616a
--- /dev/null
@@ -0,0 +1,5 @@
+
+
+void __attribute__((weak)) foo()
+{
+}
diff --git a/unit-tests/test-cases/visibility-warning/foo_weak_hidden.c b/unit-tests/test-cases/visibility-warning/foo_weak_hidden.c
new file mode 100755 (executable)
index 0000000..8d461e6
--- /dev/null
@@ -0,0 +1,5 @@
+
+
+void __attribute__((weak, visibility("hidden"))) foo()
+{
+}
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/weak_dylib/Makefile b/unit-tests/test-cases/weak_dylib/Makefile
new file mode 100755 (executable)
index 0000000..0a00a39
--- /dev/null
@@ -0,0 +1,49 @@
+##
+# Copyright (c) 2007 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
+
+all:   
+       ${CC} ${CCFLAGS} -dynamiclib  foo.c -o libfoo.dylib 
+       ${FAIL_IF_BAD_MACHO} libfoo.dylib
+
+       ${CC} ${CCFLAGS} -dynamiclib  bar.c -o libbar.dylib 
+       ${FAIL_IF_BAD_MACHO} libbar.dylib
+
+       ${CC} ${CCFLAGS} -mmacosx-version-min=10.4 main.c -o main libfoo.dylib libbar.dylib
+       # libfoo.dylib should be weakly loaded because all symbols are weakly imported
+       otool -lv main | grep -B2 libfoo.dylib | grep LC_LOAD_WEAK_DYLIB | ${FAIL_IF_EMPTY}
+       # libbar.dylib should not be weakly loaded because _bar4 is not weakly imported
+       otool -lv main | grep -B2 libbar.dylib | grep LC_LOAD_DYLIB | ${FAIL_IF_EMPTY}
+       ${PASS_IFF_GOOD_MACHO} main
+
+               
+clean:
+       rm -rf libfoo.dylib libbar.dylib main
diff --git a/unit-tests/test-cases/weak_dylib/bar.c b/unit-tests/test-cases/weak_dylib/bar.c
new file mode 100755 (executable)
index 0000000..261a806
--- /dev/null
@@ -0,0 +1,9 @@
+
+
+#include "bar.h"
+
+void bar1() {}
+void bar2() {}
+void bar3() {}
+void bar4() {}
+
diff --git a/unit-tests/test-cases/weak_dylib/bar.h b/unit-tests/test-cases/weak_dylib/bar.h
new file mode 100755 (executable)
index 0000000..7ea2ef3
--- /dev/null
@@ -0,0 +1,9 @@
+
+
+extern void bar1();
+extern void bar2() __attribute__((weak_import));
+extern void bar3();
+extern void bar4() __attribute__((weak_import));
+
+
+
diff --git a/unit-tests/test-cases/weak_dylib/foo.c b/unit-tests/test-cases/weak_dylib/foo.c
new file mode 100755 (executable)
index 0000000..aa25da5
--- /dev/null
@@ -0,0 +1,9 @@
+
+
+#include "foo.h"
+
+void foo1() {}
+void foo2() {}
+void foo3() {}
+void foo4() {}
+
diff --git a/unit-tests/test-cases/weak_dylib/foo.h b/unit-tests/test-cases/weak_dylib/foo.h
new file mode 100755 (executable)
index 0000000..54b3e36
--- /dev/null
@@ -0,0 +1,6 @@
+
+
+extern void foo1();
+extern void foo2() __attribute__((weak_import));
+extern void foo3();
+extern void foo4() __attribute__((weak_import));
diff --git a/unit-tests/test-cases/weak_dylib/main.c b/unit-tests/test-cases/weak_dylib/main.c
new file mode 100755 (executable)
index 0000000..cb61aeb
--- /dev/null
@@ -0,0 +1,22 @@
+
+#include "foo.h"
+#include "bar.h"
+
+void* p;
+
+int main (void)
+{
+       // non-lazy reference to foo2
+       p = &foo2;
+       // lazy reference to foo4
+       foo4();
+       
+       // non-lazy reference to bar2
+       p = &bar2;
+       // lazy reference to bar4 and bar1
+       bar4();
+       bar1();
+   
+   return 0;
+}
+
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/unit-tests/test-cases/why_live/Makefile b/unit-tests/test-cases/why_live/Makefile
new file mode 100755 (executable)
index 0000000..9c4811e
--- /dev/null
@@ -0,0 +1,44 @@
+##
+# Copyright (c) 2007 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
+
+SHELL = bash # use bash shell so we can redirect just stderr
+
+
+#
+# Text -why_live option with dead code stripping
+#
+
+run: all
+
+all:
+       ${CC} ${CCFLAGS} main.c foo.c bar.c -o main -dead_strip -Wl,-why_live,_bar 2>call_chains
+       grep _bar call_chains | ${FAIL_IF_EMPTY}
+       grep _foo call_chains | ${FAIL_IF_EMPTY}
+       grep _main call_chains | ${FAIL_IF_EMPTY}
+       grep _frob call_chains | ${FAIL_IF_STDIN}
+       ${PASS_IFF_GOOD_MACHO} main
+
+clean:
+       rm  main call_chains
diff --git a/unit-tests/test-cases/why_live/bar.c b/unit-tests/test-cases/why_live/bar.c
new file mode 100755 (executable)
index 0000000..e425999
--- /dev/null
@@ -0,0 +1 @@
+void bar() {}
diff --git a/unit-tests/test-cases/why_live/foo.c b/unit-tests/test-cases/why_live/foo.c
new file mode 100755 (executable)
index 0000000..9a2edf5
--- /dev/null
@@ -0,0 +1,12 @@
+
+extern void bar();
+
+void foo()
+{
+       bar();
+}
+
+void frob()
+{
+       bar();
+}
\ No newline at end of file
diff --git a/unit-tests/test-cases/why_live/main.c b/unit-tests/test-cases/why_live/main.c
new file mode 100755 (executable)
index 0000000..a5a79d5
--- /dev/null
@@ -0,0 +1,7 @@
+extern void foo();
+
+int main()
+{
+       foo();
+       return 0;
+}
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 433078b..b011e70
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
+# Copyright (c) 2006-2007 Apple Inc. All rights reserved.
 #
 # @APPLE_LICENSE_HEADER_START@
 # 
@@ -31,11 +31,8 @@ include ${TESTROOT}/include/common.makefile
 run: all
 
 all:
-       BOOST=1; \
-       [ X"${ARCH}" = Xppc64 -o X"${ARCH}" = Xx86_64 ] && BOOST=100L; \
-       ${CC} ${CCFLAGS} -DBOOST=$$BOOST test.c -mmacosx-version-min=10.4 -o test-${ARCH} -L/Developer/SDKs/MacOSX10.4u.sdk/usr/lib -L/Developer/SDKs/MacOSX10.4u.sdk/usr/lib/system
-
-       ${PASS_IFF_GOOD_MACHO} test-${ARCH}
+       ${CC} ${CCFLAGS} test.c -o test 
+       ${PASS_IFF_GOOD_MACHO} test
 
 clean:
-       rm -rf test-*
+       rm -rf test
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)
index 74144d0..219cdc2
 
 // if we used one big array, the linker would page align it
 // but we want to test a non-page align big chunk of zero-fill data
+
+#if __LP64__
+       #define BOOST 100UL
+#else
+       #define BOOST 1
+#endif
+
 int bigarray1[256];
 int bigarray2[2560];
 int bigarray3[25600];
old mode 100644 (file)
new mode 100755 (executable)
index 50399b7..6266019
@@ -43,5 +43,8 @@ test-run-x86_64 test-ppc64:
 test-ppc:
        ${PASS_IFF_ERROR} ${CC} ${CCFLAGS} -DSHRINK=4 test.c --save-temps -o test-${ARCH} 2>/dev/null
 
+test-run-armv6:
+       ${PASS_IFF_ERROR} ${CC} ${CCFLAGS} -DSHRINK=4 test.c --save-temps -o test-${ARCH} 2>/dev/null
+
 clean:
        rm -rf test-* *.o *.s *.i
old mode 100644 (file)
new mode 100755 (executable)
old mode 100644 (file)
new mode 100755 (executable)