------ Tagged ld64-84.1.2
+----- Tagged ld64-85
+
+2008-04-29 Nick Kledzik <kledzik@apple.com>
+
+ * ld64.xcodeproj/project.pbxproj: <llvm-c/lto.h> is moving from /usr/local/include to /Developer/usr/local/include
+
+
+2008-04-29 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5829579> ld doesn't honor "rightmost" -syslibroot argument
+ * src/Options.cpp: if last -syslibroot is /, then ignore all syslibroots
+
+
+2008-04-29 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5866582> GLRendererFloat has bad __eh_frame section caused by mixing llvm-gcc and gcc object files
+ * src/MachOReaderRelocatable.hpp: make all atoms in __eh_frame section have 1-byte alignment
+ * src/MachOWriterExecutable.hpp: make __eh_frame section have pointer sized alignment
+
+
+2008-04-17 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOReaderRelocatable.hpp: better cpu subtype support
+
+
+2008-04-14 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5733759> ld64 has bad ARM branch island check
+ * src/MachOWriterExecutable.hpp: in addBranchIslands() don't force large arm programs to fail
+
+
+2008-04-10 Nick Kledzik <kledzik@apple.com>
+
+ * src/MachOWriterExecutable.hpp: fix stubs used with lazy dylibs
+
+
+----- Tagged ld64-84.4
+
+2008-04-10 Nick Kledzik <kledzik@apple.com>
+
+ <rdar://problem/5847206> SPEC2000/eon built with -mdynamic-no-pic won't run
+ * src/Architectures.hpp: added arm::kReadOnlyPointer
+ * src/MachOReaderRelocatable.hpp: generate arm::kReadOnlyPointer
+ * src/MachOWriterExecutable.hpp: use arm::kReadOnlyPointer
+ * src/machochecker.cpp: allow MH_PIE bit
+ * unit-tests/test-cases/switch-jump-table: added test cases
+
+
+----- Tagged ld64-84.3
2008-04-09 Nick Kledzik <kledzik@apple.com>
* src/ld.cpp: don't create proxy atom when scanning for dylib duplicates
* unit-tests/test-cases/tentative-and-archive: use -undefined dynamic_lookup
+
+----- Tagged ld64-84.2
+
+2008-04-04 Nick Kledzik <kledzik@apple.com>
+
+ * src/ld.cpp: don't add .eh symbols to symbol table in -r mode
+ * unit-tests/test-cases/eh-coalescing-r: update to test out of order coalescing
+
+
----- Tagged ld64-84.1
2008-03-28 Nick Kledzik <kledzik@apple.com>
);
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";
+ shellScript = "if [ -f /Developer/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 */ = {
GCC_WARN_UNUSED_PARAMETER = NO;
GCC_WARN_UNUSED_VALUE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- HEADER_SEARCH_PATHS = "$(DEVELOPER_DIR)/usr/include";
+ HEADER_SEARCH_PATHS = (
+ "$(DEVELOPER_DIR)/usr/local/include",
+ "$(DEVELOPER_DIR)/usr/include",
+ );
INSTALL_PATH = /usr/bin;
MACOSX_DEPLOYMENT_TARGET = "";
OTHER_CPLUSPLUSFLAGS = "$(OTHER_CPLUSPLUSFLAGS)";
+ OTHER_LDFLAGS = "-Wl,-lazy_library,/Developer/usr/lib/libLTO.dylib";
PREBINDING = NO;
PRODUCT_NAME = ld;
SECTORDER_FLAGS = "";
GCC_WARN_UNUSED_PARAMETER = NO;
GCC_WARN_UNUSED_VALUE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
- HEADER_SEARCH_PATHS = "$(DEVELOPER_DIR)/usr/include";
+ HEADER_SEARCH_PATHS = (
+ "$(DEVELOPER_DIR)/usr/local/include",
+ "$(DEVELOPER_DIR)/usr/include",
+ );
INSTALL_PATH = /usr/bin;
OTHER_CPLUSPLUSFLAGS = "$(OTHER_CPLUSPLUSFLAGS)";
+ OTHER_LDFLAGS = "-Wl,-lazy_library,/Developer/usr/lib/libLTO.dylib";
PREBINDING = NO;
PRODUCT_NAME = ld;
SECTORDER_FLAGS = "";
{
typedef Pointer32<LittleEndian> P;
- enum ReferenceKinds { kNoFixUp, kFollowOn, kGroupSubordinate, kPointer, kPointerWeakImport, kPointerDiff,
- kBranch24, kBranch24WeakImport, kThumbBranch22, kThumbBranch22WeakImport,
+ enum ReferenceKinds { kNoFixUp, kFollowOn, kGroupSubordinate, kPointer, kPointerWeakImport, kPointerDiff, kReadOnlyPointer,
+ kBranch24, kBranch24WeakImport, kThumbBranch22, kThumbBranch22WeakImport,
kDtraceProbe, kDtraceProbeSite, kDtraceIsEnabledSite, kDtraceTypeReference };
};
// - the target kind is not regular (is weak or tentative)
if ( (kind != A::kNoFixUp) && (kind != A::kFollowOn) && (kind != A::kGroupSubordinate)
&& (toTarget.atom->getScope() != ObjectFile::Atom::scopeTranslationUnit)
- && (toTarget.atom->getDefinitionKind() != ObjectFile::Atom::kRegularDefinition) ) {
+ && (toTarget.atom->getDefinitionKind() != ObjectFile::Atom::kRegularDefinition)
+ && (toTarget.atom != at.atom) ) {
fToTargetName = toTarget.atom->getName();
//fprintf(stderr, "Reference(): changing to by-name %p %s, target scope=%d, target section=%s\n", toTarget.atom, fToTargetName, toTarget.atom->getScope(), toTarget.atom->getSectionName());
fToTarget.atom = NULL;
break;
}
+ // compute alignment
+ fAlignment = ObjectFile::Alignment(fSection->align(), fAddress % (1 << fSection->align()));
+
// compute whether this atom needs to be in symbol table
if ( (fSymbol->n_desc() & REFERENCED_DYNAMICALLY) != 0) {
fSymbolTableInclusion = ObjectFile::Atom::kSymbolTableInAndNeverStrip;
// .eh symbols exist so the linker can associate them with functions
// removing them from final linked images is a big space savings rdar://problem/4180168
fSymbolTableInclusion = ObjectFile::Atom::kSymbolTableNotIn;
+ // FDEs and CIEs are always packed together in a final linked image, so ignore section alignment
+ fAlignment = ObjectFile::Alignment(0);
}
else if ( fOwner.fOptions.fForFinalLinkedImage
&& ((section->flags() & SECTION_TYPE) == S_REGULAR)
else {
fSymbolTableInclusion = ObjectFile::Atom::kSymbolTableIn;
}
- // compute alignment
- fAlignment = ObjectFile::Alignment(fSection->align(), fAddress % (1 << fSection->align()));
// work around malformed icc generated .o files <rdar://problem/5349847>
// if section starts with a symbol and that symbol address does not match section alignment, then force it to
case CPU_SUBTYPE_ARM_V5TEJ:
case CPU_SUBTYPE_ARM_V6:
case CPU_SUBTYPE_ARM_XSCALE:
+ case CPU_SUBTYPE_ARM_V7:
fCpuConstraint = cpusubtype;
break;
default:
return fCpuConstraint;
break;
case CPU_SUBTYPE_ARM_V5TEJ:
- // v6 and xscale are more constrained than previous file (v5), so use it
+ // v6, v7, and xscale are more constrained than previous file (v5), so use it
if ( (fCpuConstraint == CPU_SUBTYPE_ARM_V6)
+ || (fCpuConstraint == CPU_SUBTYPE_ARM_V7)
|| (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)
+ // v5, v6, v7, and xscale are more constrained than previous file (v4t), so use it
+ if ( (fCpuConstraint == CPU_SUBTYPE_ARM_V7)
+ || (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
+ // v6 can run everything except xscale and v7
if ( fCpuConstraint == CPU_SUBTYPE_ARM_XSCALE )
throw "can't mix xscale and v6 code";
+ if ( fCpuConstraint == CPU_SUBTYPE_ARM_V7 )
+ return fCpuConstraint;
break;
case CPU_SUBTYPE_ARM_XSCALE:
- // xscale can run everything except v6
+ // xscale can run everything except v6 and v7
if ( fCpuConstraint == CPU_SUBTYPE_ARM_V6 )
throw "can't mix xscale and v6 code";
+ if ( fCpuConstraint == CPU_SUBTYPE_ARM_V7 )
+ throw "can't mix xscale and v7 code";
+ break;
+ case CPU_SUBTYPE_ARM_V7:
+ // v7 can run everything except xscale
+ if ( fCpuConstraint == CPU_SUBTYPE_ARM_XSCALE )
+ throw "can't mix xscale and v7 code";
break;
default:
throw "Unhandled ARM cpu subtype!";
if ( reloc->r_extern() ) {
if ( weakImport )
makeByNameReference(arm::kPointerWeakImport, srcAddr, targetName, pointerValue);
+ else if ( strcmp(sect->segname(), "__TEXT") == 0 )
+ makeByNameReference(arm::kReadOnlyPointer, srcAddr, targetName, pointerValue);
else
makeByNameReference(arm::kPointer, srcAddr, targetName, pointerValue);
}
else {
- makeReference(arm::kPointer, srcAddr, pointerValue);
+ if ( strcmp(sect->segname(), "__TEXT") == 0 )
+ makeReference(arm::kReadOnlyPointer, srcAddr, pointerValue);
+ else
+ makeReference(arm::kPointer, srcAddr, pointerValue);
}
break;
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);
+ if ( strcmp(sect->segname(), "__TEXT") == 0 )
+ makeReferenceWithToBase(arm::kReadOnlyPointer, srcAddr, betterDstAddr, dstAddr);
+ else
+ makeReferenceWithToBase(arm::kPointer, srcAddr, betterDstAddr, dstAddr);
break;
case ARM_RELOC_BR24:
fromQuotes, this->getFromTargetName(), fromQuotes, fFromTarget.offset );
return temp;
}
+ case arm::kReadOnlyPointer:
+ sprintf(temp, "offset 0x%04X, read-only pointer to ", fFixUpOffsetInSrc);
+ break;
case arm::kBranch24:
case arm::kThumbBranch22:
sprintf(temp, "offset 0x%04X, pc-rel branch fixup to ", fFixUpOffsetInSrc);
fReferences.push_back(new WriterReference<x86_64>(3, x86_64::kPCRel32, &lazyPointer));
if ( forLazyDylib ) {
if ( writer.fDyldLazyDylibHelper == NULL )
- throw "symbol dyld_lazy_dylib_stub_binding_helper not defined (usually in crt1.o/dylib1.o/bundle1.o)";
+ throw "symbol dyld_lazy_dylib_stub_binding_helper not defined (usually in lazydylib1.o)";
fReferences.push_back(new WriterReference<x86_64>(8, x86_64::kPCRel32, writer.fDyldLazyDylibHelper));
}
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)";
+ throw "symbol dyld_lazy_dylib_stub_binding_helper not defined (usually in lazydylib1.o)";
lp = new LazyPointerAtom<ppc>(writer, *writer.fDyldLazyDylibHelper, *this, forLazyDylib);
}
else {
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)";
+ throw "symbol dyld_lazy_dylib_stub_binding_helper not defined (usually in lazydylib1.o)";
lp = new LazyPointerAtom<ppc64>(writer, *writer.fDyldLazyDylibHelper, *this, forLazyDylib);
}
else {
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)";
+ throw "symbol dyld_lazy_dylib_stub_binding_helper not defined (usually in lazydylib1.o)";
helper = writer.fDyldLazyDylibHelper;
}
else {
writer.fAllSynthesizedStubs.push_back(this);
LazyPointerAtom<arm>* lp;
- if ( fWriter.fOptions.prebind() ) {
+ if ( fWriter.fOptions.prebind() && !forLazyDylib ) {
// for prebound arm, lazy pointer starts out pointing to target symbol's address
// if target is a weak definition within this linkage unit or zero if in some dylib
lp = new LazyPointerAtom<arm>(writer, target, *this, forLazyDylib);
}
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);
+ ObjectFile::Atom* helper;
+ if ( forLazyDylib ) {
+ if ( writer.fDyldLazyDylibHelper == NULL )
+ throw "symbol dyld_lazy_dylib_stub_binding_helper not defined (usually in lazydylib1.o)";
+ helper = writer.fDyldLazyDylibHelper;
+ }
+ else {
+ if ( writer.fDyldHelper == NULL )
+ throw "symbol dyld_stub_binding_helper not defined (usually in crt1.o/dylib1.o/bundle1.o)";
+ helper = writer.fDyldHelper;
+ }
+ lp = new LazyPointerAtom<arm>(writer, *helper, *this, forLazyDylib);
}
if ( pic() )
fReferences.push_back(new WriterReference<arm>(12, arm::kPointerDiff, lp, 0, this, 12));
return 0;
case arm::kPointer:
+ case arm::kReadOnlyPointer:
case arm::kPointerWeakImport:
if ( !isExtern && (ref->getTargetOffset() != 0) ) {
// use scattered reloc is target offset is non-zero
template <>
bool Writer<arm>::illegalRelocInFinalLinkedImage(const ObjectFile::Reference& ref)
{
+ if ( ref.getKind() == arm::kReadOnlyPointer ) {
+ switch ( ref.getTarget().getDefinitionKind() ) {
+ case ObjectFile::Atom::kTentativeDefinition:
+ case ObjectFile::Atom::kRegularDefinition:
+ case ObjectFile::Atom::kWeakDefinition:
+ // illegal in dylibs/bundles, until we support TEXT relocs
+ return fSlideable;
+ case ObjectFile::Atom::kExternalDefinition:
+ case ObjectFile::Atom::kExternalWeakDefinition:
+ // illegal until we support TEXT relocs
+ return true;
+ case ObjectFile::Atom::kAbsoluteSymbol:
+ // absolute symbbols only allowed in static executables
+ return ( fOptions.outputKind() != Options::kStaticExecutable);
+ }
+ }
return false;
}
return false;
}
-template <typename A>
-bool Writer<A>::generatesLocalTextReloc(const ObjectFile::Reference&, const ObjectFile::Atom& atom, SectionInfo* curSection)
+template <>
+bool Writer<arm>::generatesLocalTextReloc(const ObjectFile::Reference& ref, const ObjectFile::Atom& atom, SectionInfo* atomSection)
{
+ if ( ref.getKind() == arm::kReadOnlyPointer ) {
+ 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<x86_64>::generatesLocalTextReloc(const ObjectFile::Reference&, const ObjectFile::Atom& atom, SectionInfo* curSection)
+{
+ // text relocs not supported (usually never needed because of RIP addressing)
+ return false;
+}
+
+template <>
+bool Writer<ppc64>::generatesLocalTextReloc(const ObjectFile::Reference&, const ObjectFile::Atom& atom, SectionInfo* curSection)
+{
+ // text relocs not supported
return false;
}
case arm::kNoFixUp:
case arm::kGroupSubordinate:
case arm::kPointer:
- case arm::kPointerWeakImport:
+ case arm::kPointerWeakImport:
+ case arm::kReadOnlyPointer:
// ignore
break;
default:
LittleEndian::set32(*fixUp,
(ref->getTarget().getAddress() + ref->getTargetOffset()) - (ref->getFromTarget().getAddress() + ref->getFromTargetOffset()) );
break;
+ case arm::kReadOnlyPointer:
+ switch ( ref->getTarget().getDefinitionKind() ) {
+ case ObjectFile::Atom::kRegularDefinition:
+ case ObjectFile::Atom::kWeakDefinition:
+ case ObjectFile::Atom::kTentativeDefinition:
+ // pointer contains target address
+ LittleEndian::set32(*fixUp, ref->getTarget().getAddress() + ref->getTargetOffset());
+ break;
+ case ObjectFile::Atom::kExternalDefinition:
+ case ObjectFile::Atom::kExternalWeakDefinition:
+ // external relocation ==> pointer contains addend
+ LittleEndian::set32(*fixUp, ref->getTargetOffset());
+ break;
+ case ObjectFile::Atom::kAbsoluteSymbol:
+ // pointer contains target address
+ LittleEndian::set32(*fixUp, ref->getTarget().getSectionOffset() + ref->getTargetOffset());
+ break;
+ }
+ break;
case arm::kBranch24WeakImport:
case arm::kBranch24:
displacement = targetAddr - (inAtom->getAddress() + ref->getFixUpOffset());
// do nothing
break;
case arm::kPointer:
+ case arm::kReadOnlyPointer:
case arm::kPointerWeakImport:
{
if ( ((SectionInfo*)inAtom->getSection())->fAllNonLazyPointers ) {
case arm::kDtraceTypeReference:
// nothing to fix up
break;
- default:
- throw "unhandled arm refernce kind";
}
}
case arm::kFollowOn:
case arm::kGroupSubordinate:
case arm::kPointer:
+ case arm::kReadOnlyPointer:
case arm::kPointerWeakImport:
case arm::kPointerDiff:
case arm::kDtraceProbe:
currentSectionInfo->fAllSelfModifyingStubs = true;
currentSectionInfo->fAlignment = 6; // force x86 fast stubs to start on 64-byte boundary
}
+ if ( (strcmp(currentSectionInfo->fSegmentName, "__TEXT") == 0) && (strcmp(currentSectionInfo->fSectionName, "__eh_frame") == 0) )
+ currentSectionInfo->fAlignment = __builtin_ctz(sizeof(pint_t)); // always start CFI info pointer aligned
curSection = atom->getSection();
if ( currentSectionInfo->fAllNonLazyPointers || currentSectionInfo->fAllLazyPointers || currentSectionInfo->fAllLazyDylibPointers
|| currentSectionInfo->fAllStubs || currentSectionInfo->fAllSelfModifyingStubs ) {
template <>
bool Writer<arm>::addBranchIslands()
{
- if ( fLoadCommandsSegment->fSize > 16000000 )
- throw "arm branch islands unimplemented"; // FIXME: implement this
+ // arm branch islands not (yet) supported
+ // you can instead compile with -mlong-call
return false;
}
#include <fcntl.h>
#include "MachOReaderRelocatable.hpp"
-#include "LTOReader.hpp"
+
+#define LTO_SUPPORT 1
+
+#if LTO_SUPPORT
+ #include "LTOReader.hpp"
+#endif
static bool sDumpContent= true;
static bool sDumpStabs = false;
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_SUPPORT
if ( lto::Reader::validFile(p, stat_buf.st_size, 0) ) {
return new lto::Reader(p, stat_buf.st_size, path, 0, options, 0);
}
+#endif
throwf("not a mach-o object file: %s", path);
}
//frameworkPaths.push_back("/Network/Library/Frameworks/");
}
+ // <rdar://problem/5829579> Support for configure based hacks
+ // if last -syslibroot is /, then ignore all syslibroots
+ if ( fSDKPaths.size() > 0 ) {
+ if ( strcmp(fSDKPaths.back(), "/") == 0 ) {
+ fSDKPaths.clear();
+ }
+ }
+
// now merge sdk and library paths to make real search paths
fLibrarySearchPaths.reserve(libraryPaths.size()*(fSDKPaths.size()+1));
for (std::vector<const char*>::iterator it = libraryPaths.begin(); it != libraryPaths.end(); it++) {
}
}
// add to symbol table
- fGlobalSymbolTable.add(atom);
+ if ( fOptions.outputKind() == Options::kObjectFile ) {
+ // in ld -r mode don't add .eh symbols to symbol table
+ // instead kGroupSubordinate references will keep them paired
+ // with their functions.
+ const char* sectionName = atom.getSectionName();
+ if ( (sectionName != NULL) && (strcmp(sectionName, "__eh_frame") != 0) )
+ fGlobalSymbolTable.add(atom);
+ }
+ else {
+ fGlobalSymbolTable.add(atom);
+ }
}
// record section orders so output file can have same order
throw "sizeofcmds in mach_header is larger than file";
uint32_t flags = fHeader->flags();
- const uint32_t invalidBits = MH_INCRLINK | MH_LAZY_INIT | 0xFFE00000;
+ const uint32_t invalidBits = MH_INCRLINK | MH_LAZY_INIT | 0xFFC00000;
if ( flags & invalidBits )
throw "invalid bits in mach_header flags";
if ( (flags & MH_NO_REEXPORTED_DYLIBS) && (fHeader->filetype() != MH_DYLIB) )
all_archs="x86_64 armv6 thumb ppc ppc64 i386 "
valid_archs="x86_64 armv6 ppc ppc64 i386 "
+# clean first
+../bin/make-recursive.pl clean > /dev/null
+
mkdir /tmp/$$
for arch in $all_archs
do
--- /dev/null
+##
+# 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
+
+ifeq ($(ARCH),armv6)
+ ARCH_FLAGS = -mlong-branch
+else
+ ARCH_FLAGS =
+endif
+
+
+
+#
+# Simple test for branch islands
+#
+
+run: all
+
+
+
+all:
+ ${CC} ${CCFLAGS} hello.c space.s extra.c -o hello ${ARCH_FLAGS}
+ ${PASS_IFF_GOOD_MACHO} hello
+
+clean:
+ rm hello
--- /dev/null
+#include <stdio.h>
+
+
+void foo()
+{
+ fprintf(stdout, "foo\n");
+}
+
--- /dev/null
+#include <stdio.h>
+
+extern void foo();
+
+int main()
+{
+ fprintf(stdout, "hello\n");
+ foo();
+}
+
--- /dev/null
+
+#if __ppc__
+
+ .text
+
+_prejunk:
+ mr r3,r5
+ mr r3,r4
+ blr
+
+
+_space1:
+ .space 15*1024*1024 + 2
+
+ .align 5
+_junk:
+ mr r3,r5
+ mr r3,r4
+ blr
+
+
+_space2:
+ .space 2*1024*1024
+
+#endif
+
+
+#if __arm__
+
+
+_space1:
+ .space 32*1024*1024 + 2
+
+
+#endif
+
+
+ .subsections_via_symbols
+
\ No newline at end of file
#
# <rdar://problem/5726215> comdat warnings in ld -r
#
-
+# also use -falign-functions to force an out of order coalesing
+#
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
+ ${CXX} ${CCXXFLAGS} bar.cxx -c -o bar.o -falign-functions=32
+ ${CXX} ${CCXXFLAGS} baz.cxx -c -o baz.o
+ ${LD} -r foo.o bar.o baz.o -o foobarbaz.o 2> warnings.log
grep warning warnings.log | ${PASS_IFF_EMPTY}
clean:
- rm foo.o bar.o foobar.o warnings.log
+ rm foo.o bar.o baz.o foobarbaz.o warnings.log
--- /dev/null
+##
+# 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 -mdynamic-no-pic jump table in the middle of
+# a function does not cause relocations.
+#
+# <rdar://problem/5847206> SPEC2000/eon built with -mdynamic-no-pic won't run
+#
+
+run: all
+
+all:
+ # check jump table in a weak function
+ ${CC} ${CCFLAGS} main.c switch.s -o main
+ otool -rv main | grep _foo | ${FAIL_IF_STDIN}
+ otool -rv main | grep _bar | ${FAIL_IF_STDIN}
+ # check jump table in a regular function with -flat_namespace
+ ${CC} ${CCFLAGS} main.c switch.s -o main -flat_namespace
+ otool -rv main | grep _foo | ${FAIL_IF_STDIN}
+ otool -rv main | grep _bar | ${FAIL_IF_STDIN}
+ # check jump table in a regular function that is interposable
+ ${CC} ${CCFLAGS} main.c switch.s -o main -Wl,-interposable_list,interpose.exp
+ otool -rv main | grep _foo | ${FAIL_IF_STDIN}
+ otool -rv main | grep _bar | ${FAIL_IF_STDIN}
+ # check jump table with -pie, should have no external and some local relocations
+ ${CC} ${CCFLAGS} main.c switch.s -o main -Wl,-pie -read_only_relocs suppress
+ otool -rv main | grep "External relocation" | ${FAIL_IF_STDIN}
+ otool -rv main | grep "Local relocation" | ${FAIL_IF_EMPTY}
+ ${PASS_IFF_GOOD_MACHO} main
+
+
+clean:
+ rm -f main
--- /dev/null
+_foo
+_bar
--- /dev/null
+int main()
+{
+ return 0;
+}
\ No newline at end of file
--- /dev/null
+
+ .section __TEXT,__textcoal_nt,coalesced,pure_instructions
+
+
+
+/*
+ Simulate a switch statement in a weak function compiled
+ to a jump table
+*/
+ .globl _foo
+ .weak_definition _foo
+_foo:
+ nop
+ nop
+#if __arm__ || __i386__
+ .long L1
+ .long L2
+ .long L3
+#endif
+ nop
+L1: nop
+L2: nop
+L3: nop
+ nop
+
+
+/*
+ Simulate a switch statement in a regular function compiled
+ to a jump table
+*/
+ .text
+ .globl _bar
+_bar: nop
+ nop
+ nop
+ nop
+#if __arm__ || __i386__
+ .long L5
+ .long L6
+ .long L7
+#endif
+ nop
+L5: nop
+L6: nop
+L7: nop
+ nop
+
+
+