X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/55e3d2f687f4ed9653982dbda92c6a055b0a8350..d425e3882ca60fabae080ddb890789ef2e73a66b:/src/other/rebase.cpp diff --git a/src/other/rebase.cpp b/src/other/rebase.cpp index f8dc1ee..e2776cf 100644 --- a/src/other/rebase.cpp +++ b/src/other/rebase.cpp @@ -1,6 +1,6 @@ /* -*- 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@ * @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -302,7 +303,6 @@ void Rebaser::setBaseAddress(uint64_t addr) template void Rebaser::adjustLoadCommands() { - const macho_segment_command

* highestSegmentCmd = NULL; const macho_load_command

* const cmds = (macho_load_command

*)((uint8_t*)fHeader + sizeof(macho_header

)); const uint32_t cmd_count = fHeader->ncmds(); const macho_load_command

* cmd = cmds; @@ -317,6 +317,8 @@ void Rebaser::adjustLoadCommands() 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

* dylib = (macho_dylib_command

*)cmd; @@ -326,7 +328,7 @@ void Rebaser::adjustLoadCommands() case macho_routines_command

::CMD: // update -init command { - struct macho_routines_command

* routines = (struct macho_routines_command

*)cmd; + macho_routines_command

* routines = (macho_routines_command

*)cmd; routines->set_init_address(routines->init_address() + fSlide); } break; @@ -374,6 +376,7 @@ void Rebaser::adjustSymbolTable() { const macho_dysymtab_command

* dysymtab = NULL; macho_nlist

* symbolTable = NULL; + const char* strings = NULL; // get symbol table info const macho_load_command

* const cmds = (macho_load_command

*)((uint8_t*)fHeader + sizeof(macho_header

)); @@ -385,7 +388,8 @@ void Rebaser::adjustSymbolTable() { const macho_symtab_command

* symtab = (macho_symtab_command

*)cmd; symbolTable = (macho_nlist

*)(((uint8_t*)fHeader) + symtab->symoff()); - } + strings = (char*)(((uint8_t*)fHeader) + symtab->stroff()); + } break; case LC_DYSYMTAB: dysymtab = (macho_dysymtab_command

*)cmd; @@ -404,8 +408,23 @@ void Rebaser::adjustSymbolTable() // walk all local symbols and slide their n_value macho_nlist

* lastLocal = &symbolTable[dysymtab->ilocalsym()+dysymtab->nlocalsym()]; for (macho_nlist

* 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 @@ -448,7 +467,7 @@ void Rebaser::rebaseAt(int segIndex, uint64_t offset, uint8_t type) if ( segIndex == segCount ) { const macho_segment_command

* seg = (macho_segment_command

*)cmd; lastSegMappedStart = (uint8_t*)fHeader + seg->fileoff(); - lastSegIndex == segCount; + lastSegIndex = segCount; break; } ++segCount; @@ -632,13 +651,7 @@ void Rebaser::doLocalRelocation(const macho_relocation_info

* reloc) } } else { - macho_scattered_relocation_info

* sreloc = (macho_scattered_relocation_info

*)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"; } } @@ -662,6 +675,7 @@ void Rebaser::doLocalRelocation(const macho_relocation_info

* reloc) } } +#if SUPPORT_ARCH_arm_any template <> void Rebaser::doLocalRelocation(const macho_relocation_info

* reloc) { @@ -681,6 +695,7 @@ void Rebaser::doLocalRelocation(const macho_relocation_info

* reloc) } } } +#endif template void Rebaser::doLocalRelocation(const macho_relocation_info

* reloc) @@ -996,21 +1011,18 @@ int main(int argc, const char* argv[]) 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();