X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/55e3d2f687f4ed9653982dbda92c6a055b0a8350..afe874b1634377ecb27057ee76deb04915bb34d7:/src/other/rebase.cpp diff --git a/src/other/rebase.cpp b/src/other/rebase.cpp index f8dc1ee..d69fc3c 100644 --- a/src/other/rebase.cpp +++ b/src/other/rebase.cpp @@ -302,7 +302,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 +316,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 +327,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 +375,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 +387,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 +407,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 +466,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; @@ -1005,12 +1023,18 @@ 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); + else { + bool found = false; + for (const ARMSubType* t=ARMSubTypes; t->subTypeName != NULL; ++t) { + if ( strcmp(t->subTypeName,arch) == 0 ) { + onlyArchs.insert(CPU_TYPE_ARM); + found = true; + break; + } + } + if ( !found ) + throwf("unknown architecture %s", arch); + } } else { usage();