X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/55e3d2f687f4ed9653982dbda92c6a055b0a8350..a645023da60d22e86be13f7b4d97adeff8bc6665:/src/other/rebase.cpp diff --git a/src/other/rebase.cpp b/src/other/rebase.cpp index f8dc1ee..c04fb0a 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;