/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
*
- * Copyright (c) 2006-2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2006-2012 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
+#include <stdlib.h>
#include <vector>
#include <set>
template <typename A>
void Rebaser<A>::adjustLoadCommands()
{
- const macho_segment_command<P>* highestSegmentCmd = NULL;
const macho_load_command<P>* const cmds = (macho_load_command<P>*)((uint8_t*)fHeader + sizeof(macho_header<P>));
const uint32_t cmd_count = fHeader->ncmds();
const macho_load_command<P>* cmd = cmds;
break;
case LC_LOAD_DYLIB:
case LC_LOAD_WEAK_DYLIB:
+ case LC_REEXPORT_DYLIB:
+ case LC_LOAD_UPWARD_DYLIB:
if ( (fHeader->flags() & MH_PREBOUND) != 0 ) {
// clear expected timestamps so that this image will load with invalid prebinding
macho_dylib_command<P>* dylib = (macho_dylib_command<P>*)cmd;
case macho_routines_command<P>::CMD:
// update -init command
{
- struct macho_routines_command<P>* routines = (struct macho_routines_command<P>*)cmd;
+ macho_routines_command<P>* routines = (macho_routines_command<P>*)cmd;
routines->set_init_address(routines->init_address() + fSlide);
}
break;
{
const macho_dysymtab_command<P>* dysymtab = NULL;
macho_nlist<P>* symbolTable = NULL;
+ const char* strings = NULL;
// get symbol table info
const macho_load_command<P>* const cmds = (macho_load_command<P>*)((uint8_t*)fHeader + sizeof(macho_header<P>));
{
const macho_symtab_command<P>* symtab = (macho_symtab_command<P>*)cmd;
symbolTable = (macho_nlist<P>*)(((uint8_t*)fHeader) + symtab->symoff());
- }
+ strings = (char*)(((uint8_t*)fHeader) + symtab->stroff());
+ }
break;
case LC_DYSYMTAB:
dysymtab = (macho_dysymtab_command<P>*)cmd;
// walk all local symbols and slide their n_value
macho_nlist<P>* lastLocal = &symbolTable[dysymtab->ilocalsym()+dysymtab->nlocalsym()];
for (macho_nlist<P>* entry = &symbolTable[dysymtab->ilocalsym()]; entry < lastLocal; ++entry) {
- if ( entry->n_sect() != NO_SECT )
+ if ( ((entry->n_type() & N_STAB) == 0) && ((entry->n_type() & N_TYPE) == N_SECT) ) {
entry->set_n_value(entry->n_value() + fSlide);
+ }
+ else if ( entry->n_type() & N_STAB ) {
+ // some stabs need to be slid too
+ switch ( entry->n_type() ) {
+ case N_FUN:
+ // don't slide end-of-function FUN which is FUN with no string
+ if ( (entry->n_strx() == 0) || (strings[entry->n_strx()] == '\0') )
+ break;
+ case N_BNSYM:
+ case N_STSYM:
+ case N_LCSYM:
+ entry->set_n_value(entry->n_value() + fSlide);
+ break;
+ }
+ }
}
// FIXME ¥¥¥ adjust dylib_module if it exists
if ( segIndex == segCount ) {
const macho_segment_command<P>* seg = (macho_segment_command<P>*)cmd;
lastSegMappedStart = (uint8_t*)fHeader + seg->fileoff();
- lastSegIndex == segCount;
+ lastSegIndex = segCount;
break;
}
++segCount;
}
}
else {
- macho_scattered_relocation_info<P>* sreloc = (macho_scattered_relocation_info<P>*)reloc;
- if ( sreloc->r_type() == PPC_RELOC_PB_LA_PTR ) {
- sreloc->set_r_value( sreloc->r_value() + fSlide );
- }
- else {
- throw "cannot rebase final linked image with scattered relocations";
- }
+ throw "cannot rebase final linked image with scattered relocations";
}
}
}
}
+#if SUPPORT_ARCH_arm_any
template <>
void Rebaser<arm>::doLocalRelocation(const macho_relocation_info<P>* reloc)
{
}
}
}
+#endif
template <typename A>
void Rebaser<A>::doLocalRelocation(const macho_relocation_info<P>* reloc)
highAddress = strtoull(argv[++i], &endptr, 16);
}
else if ( strcmp(arg, "-arch") == 0 ) {
- const char* arch = argv[++i];
- if ( strcmp(arch, "ppc") == 0 )
- onlyArchs.insert(CPU_TYPE_POWERPC);
- else if ( strcmp(arch, "ppc64") == 0 )
- onlyArchs.insert(CPU_TYPE_POWERPC64);
- else if ( strcmp(arch, "i386") == 0 )
- 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);
+ const char* archName = argv[++i];
+ if ( archName == NULL )
+ throw "-arch missing architecture name";
+ bool found = false;
+ for (const ArchInfo* t=archInfoArray; t->archName != NULL; ++t) {
+ if ( strcmp(t->archName,archName) == 0 ) {
+ onlyArchs.insert(t->cpuType);
+ found = true;
+ }
+ }
+ if ( !found )
+ throwf("unknown architecture %s", archName);
}
else {
usage();