From 721fc5d53593275c3b62d65a5eb66a2d83227ba3 Mon Sep 17 00:00:00 2001 From: "Kyle J. McKay" Date: Sun, 15 Apr 2012 04:23:54 -0700 Subject: [PATCH] Integrate cctools-822 changes --- Makefile | 2 + README.txt | 8 +- include/mach-o/loader.h | 66 +++++++++- include/mach-o/nlist.h | 2 +- include/stuff/breakout.h | 8 ++ include/stuff/bytesex.h | 8 ++ libstuff/bytesex.c | 23 ++++ libstuff/checkout.c | 24 ++++ libstuff/ofile.c | 180 ++++++++++++------------- libstuff/swap_headers.c | 58 ++++++++ libstuff/writeout.c | 24 ++++ strip.c | 330 +++++++++++++++++++++++++++++----------------- tease.c | 337 +++++++++++++++++++++++++++++------------------ version.c | 4 + 14 files changed, 723 insertions(+), 351 deletions(-) create mode 100644 version.c diff --git a/Makefile b/Makefile index 2cce8f5..401ba51 100644 --- a/Makefile +++ b/Makefile @@ -92,10 +92,12 @@ LIBSTUFF_SRC := $(wildcard libstuff/*.c) TEASE_SRC = \ tease.c \ + version.c \ $(LIBSTUFF_SRC) STRIP_SRC = \ strip.c \ + version.c \ $(LIBSTUFF_SRC) TEASE_OBJS = $(addprefix $(DD),$(TEASE_SRC:.c=.o)) diff --git a/README.txt b/README.txt index 82a907b..112af02 100644 --- a/README.txt +++ b/README.txt @@ -18,12 +18,12 @@ and only strip the relevant Mach-O load commands without removing anything from the symbol table. striptease is based on strip.c and other supporting files in Apple's -cctools package. This version of striptease is based on cctools-809, -corresponding to Xcode Tools 4.2 and Mac OS X 10.7. It builds properly +cctools package. This version of striptease is based on cctools-822, +corresponding to Xcode Tools 4.3 and Mac OS X 10.7. It builds properly under Xcode Tools 2.x on Mac OS X 10.4, as well. The cctools package is available from: -http://opensource.apple.com/tarballs/cctools/cctools-809.tar.gz +http://opensource.apple.com/tarballs/cctools/cctools-822.tar.gz cctools, and therefore strip, are available under the APSL license: @@ -43,4 +43,4 @@ Use "make clean" to remove the build directory and built executables. Note that when building on 10.6 or 10.7, the MacOSX10.5.sdk must be present. Also note that compile warnings (and link warnings when building on 10.4) -should be ignored -- the cctools-809 sources have some issues with warnings. +should be ignored -- the cctools-822 sources have some issues with warnings. diff --git a/include/mach-o/loader.h b/include/mach-o/loader.h index ff18e29..f41664e 100644 --- a/include/mach-o/loader.h +++ b/include/mach-o/loader.h @@ -290,6 +290,11 @@ struct load_command { #define LC_FUNCTION_STARTS 0x26 /* compressed table of function start addresses */ #define LC_DYLD_ENVIRONMENT 0x27 /* string for dyld to treat like environment variable */ +#define LC_MAIN (0x28|LC_REQ_DYLD) /* replacement for LC_UNIXTHREAD */ +#define LC_DATA_IN_CODE 0x29 /* table of non-instructions in __text */ +#define LC_SOURCE_VERSION 0x2A /* source version used to build binary */ +#define LC_DYLIB_CODE_SIGN_DRS 0x2B /* Code signing DRs copied from linked dylibs */ + /* * A variable length string in a load command is represented by an lc_str @@ -1149,7 +1154,8 @@ struct rpath_command { */ struct linkedit_data_command { uint32_t cmd; /* LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO, - or LC_FUNCTION_STARTS */ + LC_FUNCTION_STARTS, LC_DATA_IN_CODE, + or LC_DYLIB_CODE_SIGN_DRS */ uint32_t cmdsize; /* sizeof(struct linkedit_data_command) */ uint32_t dataoff; /* file offset of data in __LINKEDIT segment */ uint32_t datasize; /* file size of data in __LINKEDIT segment */ @@ -1177,7 +1183,7 @@ struct version_min_command { LC_VERSION_MIN_IPHONEOS */ uint32_t cmdsize; /* sizeof(struct min_version_command) */ uint32_t version; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ - uint32_t reserved; /* zero */ + uint32_t sdk; /* X.Y.Z is encoded in nibbles xxxx.yy.zz */ }; /* @@ -1265,14 +1271,19 @@ struct dyld_info_command { * Nodes for a symbol start with a uleb128 that is the length of * the exported symbol information for the string so far. * If there is no exported symbol, the node starts with a zero byte. - * If there is exported info, it follows the length. First is - * a uleb128 containing flags. Normally, it is followed by a - * uleb128 encoded offset which is location of the content named + * If there is exported info, it follows the length. + * + * First is a uleb128 containing flags. Normally, it is followed by + * a uleb128 encoded offset which is location of the content named * by the symbol from the mach_header for the image. If the flags * is EXPORT_SYMBOL_FLAGS_REEXPORT, then following the flags is * a uleb128 encoded library ordinal, then a zero terminated * UTF8 string. If the string is zero length, then the symbol * is re-export from the specified dylib with the same name. + * If the flags is EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER, then following + * the flags is two uleb128s: the stub offset and the resolver offset. + * The stub is used by non-lazy pointers. The resolver is used + * by lazy pointers and must be called to get the actual address to use. * * After the optional exported symbol information is a byte of * how many edges (0-255) that this node has leaving it, @@ -1388,6 +1399,51 @@ struct fvmfile_command { uint32_t header_addr; /* files virtual address */ }; + +/* + * The entry_point_command is a replacement for thread_command. + * It is used for main executables to specify the location (file offset) + * of main(). If -stack_size was used at link time, the stacksize + * field will contain the stack size need for the main thread. + */ +struct entry_point_command { + uint32_t cmd; /* LC_MAIN only used in MH_EXECUTE filetypes */ + uint32_t cmdsize; /* 24 */ + uint64_t entryoff; /* file (__TEXT) offset of main() */ + uint64_t stacksize;/* if not zero, initial stack size */ +}; + + +/* + * The source_version_command is an optional load command containing + * the version of the sources used to build the binary. + */ +struct source_version_command { + uint32_t cmd; /* LC_SOURCE_VERSION */ + uint32_t cmdsize; /* 16 */ + uint64_t version; /* A.B.C.D.E packed as a24.b10.c10.d10.e10 */ +}; + + +/* + * The LC_DATA_IN_CODE load commands uses a linkedit_data_command + * to point to an array of data_in_code_entry entries. Each entry + * describes a range of data in a code section. This load command + * is only used in final linked images. + */ +struct data_in_code_entry { + uint32_t offset; /* from mach_header to start of data range*/ + uint16_t length; /* number of bytes in data range */ + uint16_t kind; /* a DICE_KIND_* value */ +}; +#define DICE_KIND_DATA 0x0001 /* L$start$data$... label */ +#define DICE_KIND_JUMP_TABLE8 0x0002 /* L$start$jt8$... label */ +#define DICE_KIND_JUMP_TABLE16 0x0003 /* L$start$jt16$... label */ +#define DICE_KIND_JUMP_TABLE32 0x0004 /* L$start$jt32$... label */ +#define DICE_KIND_ABS_JUMP_TABLE32 0x0005 /* L$start$jta32$... label */ + + + /* * Sections of type S_THREAD_LOCAL_VARIABLES contain an array * of tlv_descriptor structures. diff --git a/include/mach-o/nlist.h b/include/mach-o/nlist.h index 1c19410..dd19888 100644 --- a/include/mach-o/nlist.h +++ b/include/mach-o/nlist.h @@ -78,7 +78,7 @@ struct nlist { #ifndef __LP64__ char *n_name; /* for use when in-core */ #endif - int32_t n_strx; /* index into the string table */ + uint32_t n_strx; /* index into the string table */ } n_un; uint8_t n_type; /* type flag, see below */ uint8_t n_sect; /* section number or NO_SECT */ diff --git a/include/stuff/breakout.h b/include/stuff/breakout.h index fae35a2..7f97153 100644 --- a/include/stuff/breakout.h +++ b/include/stuff/breakout.h @@ -148,6 +148,10 @@ struct object { *split_info_cmd; /* the split info load command, if any*/ struct linkedit_data_command *func_starts_info_cmd; /* the func starts load command, if any*/ + struct linkedit_data_command + *data_in_code_cmd; /* the data in code load command, if any */ + struct linkedit_data_command + *code_sign_drs_cmd; /* the code signing DRs command, if any */ struct section **sections; /* array of 32-bit section structs */ struct section_64 **sections64; /* array of 64-bit section structs */ struct dyld_info_command @@ -192,6 +196,10 @@ struct object { uint32_t output_split_info_data_size; char *output_func_start_info_data; uint32_t output_func_start_info_data_size; + char *output_data_in_code_info_data; + uint32_t output_data_in_code_info_data_size; + char *output_code_sign_drs_info_data; + uint32_t output_code_sign_drs_info_data_size; uint32_t output_ilocalsym; uint32_t output_nlocalsym; diff --git a/include/stuff/bytesex.h b/include/stuff/bytesex.h index 698547e..a4d46c6 100644 --- a/include/stuff/bytesex.h +++ b/include/stuff/bytesex.h @@ -351,6 +351,14 @@ __private_extern__ void swap_dyld_info_command( struct dyld_info_command *dc, enum byte_sex target_byte_sex); +__private_extern__ void swap_entry_point_command( + struct entry_point_command *ep, + enum byte_sex target_byte_sex); + +__private_extern__ void swap_source_version_command( + struct source_version_command *sv, + enum byte_sex target_byte_sex); + __private_extern__ void swap_nlist( struct nlist *symbols, uint32_t nsymbols, diff --git a/libstuff/bytesex.c b/libstuff/bytesex.c index 9f6a311..081b871 100644 --- a/libstuff/bytesex.c +++ b/libstuff/bytesex.c @@ -2551,6 +2551,29 @@ enum byte_sex target_byte_sex) __private_extern__ void +swap_entry_point_command( +struct entry_point_command *ep, +enum byte_sex target_byte_sex) +{ + ep->cmd = SWAP_INT(ep->cmd); + ep->cmdsize = SWAP_INT(ep->cmdsize); + ep->entryoff = SWAP_LONG_LONG(ep->entryoff); + ep->stacksize = SWAP_LONG_LONG(ep->stacksize); +} + +__private_extern__ +void +swap_source_version_command( +struct source_version_command *sv, +enum byte_sex target_byte_sex) +{ + sv->cmd = SWAP_INT(sv->cmd); + sv->cmdsize = SWAP_INT(sv->cmdsize); + sv->version = SWAP_LONG_LONG(sv->version); +} + +__private_extern__ +void swap_nlist( struct nlist *symbols, uint32_t nsymbols, diff --git a/libstuff/checkout.c b/libstuff/checkout.c index 625536a..5b893c1 100644 --- a/libstuff/checkout.c +++ b/libstuff/checkout.c @@ -141,6 +141,20 @@ struct object *object) object->func_starts_info_cmd = (struct linkedit_data_command *)lc; } + else if(lc->cmd == LC_DATA_IN_CODE){ + if(object->data_in_code_cmd != NULL) + fatal_arch(arch, member, "malformed file (more than one " + "LC_DATA_IN_CODE load command): "); + object->data_in_code_cmd = + (struct linkedit_data_command *)lc; + } + else if(lc->cmd == LC_DYLIB_CODE_SIGN_DRS){ + if(object->code_sign_drs_cmd != NULL) + fatal_arch(arch, member, "malformed file (more than one " + "LC_DYLIB_CODE_SIGN_DRS load command): "); + object->code_sign_drs_cmd = + (struct linkedit_data_command *)lc; + } else if((lc->cmd == LC_DYLD_INFO) ||(lc->cmd == LC_DYLD_INFO_ONLY)){ if(object->dyld_info != NULL) fatal_arch(arch, member, "malformed file (more than one " @@ -370,6 +384,16 @@ struct object *object) order_error(arch, member, "function starts data out of place"); offset += object->func_starts_info_cmd->datasize; } + if(object->data_in_code_cmd != NULL){ + if(object->data_in_code_cmd->dataoff != offset) + order_error(arch, member, "data in code info out of place"); + offset += object->data_in_code_cmd->datasize; + } + if(object->code_sign_drs_cmd != NULL){ + if(object->code_sign_drs_cmd->dataoff != offset) + order_error(arch, member, "code signing DRs info out of place"); + offset += object->code_sign_drs_cmd->datasize; + } if(object->st->nsyms != 0){ if(object->st->symoff != offset) order_error(arch, member, "symbol table out of place"); diff --git a/libstuff/ofile.c b/libstuff/ofile.c index d9fdd92..c587264 100644 --- a/libstuff/ofile.c +++ b/libstuff/ofile.c @@ -3316,7 +3316,7 @@ struct ofile *ofile) #else /* !defined OTOOL */ uint32_t size, i, j, ncmds, sizeofcmds, load_command_multiple, sizeofhdrs; cpu_type_t cputype; - char *addr, *cmd_name; + char *addr, *cmd_name, *element_name; enum byte_sex host_byte_sex; enum bool swapped; struct mach_header *mh; @@ -3342,13 +3342,16 @@ struct ofile *ofile) struct routines_command *rc; struct routines_command_64 *rc64; struct twolevel_hints_command *hints; - struct linkedit_data_command *code_sig, *split_info, *func_starts; + struct linkedit_data_command *code_sig, *split_info, *func_starts, + *data_in_code, *code_sign_drs, *linkedit_data; struct version_min_command *vers; struct prebind_cksum_command *cs; struct encryption_info_command *encrypt_info; struct dyld_info_command *dyld_info; struct uuid_command *uuid; struct rpath_command *rpath; + struct entry_point_command *ep; + struct source_version_command *sv; uint32_t flavor, count, nflavor; char *p, *state; uint32_t sizeof_nlist, sizeof_dylib_module; @@ -3438,6 +3441,8 @@ struct ofile *ofile) hints = NULL; code_sig = NULL; func_starts = NULL; + data_in_code = NULL; + code_sign_drs = NULL; split_info = NULL; cs = NULL; uuid = NULL; @@ -3987,129 +3992,94 @@ struct ofile *ofile) goto return_bad; break; - case LC_CODE_SIGNATURE: - if(l.cmdsize < sizeof(struct linkedit_data_command)){ - Mach_O_error(ofile, "malformed object (LC_CODE_SIGNATURE " - "cmdsize too small) in command %u", i); + case LC_SEGMENT_SPLIT_INFO: + cmd_name = "LC_SEGMENT_SPLIT_INFO"; + element_name = "split info data"; + if(split_info != NULL){ + Mach_O_error(ofile, "malformed object (more than one " + "%s command)", cmd_name); goto return_bad; } + split_info = (struct linkedit_data_command *)lc; + goto check_linkedit_data_command; + + case LC_CODE_SIGNATURE: + cmd_name = "LC_CODE_SIGNATURE"; + element_name = "code signature data"; if(code_sig != NULL){ Mach_O_error(ofile, "malformed object (more than one " - "LC_CODE_SIGNATURE command)"); + "%s command)", cmd_name); goto return_bad; } code_sig = (struct linkedit_data_command *)lc; - if(swapped) - swap_linkedit_data_command(code_sig, host_byte_sex); - if(code_sig->cmdsize != sizeof(struct linkedit_data_command)){ - Mach_O_error(ofile, "malformed object (LC_CODE_SIGNATURE " - "command %u has incorrect cmdsize)", i); - goto return_bad; - } - if(code_sig->dataoff > size){ - Mach_O_error(ofile, "truncated or malformed object " - "(dataoff field of LC_CODE_SIGNATURE command %u " - "extends past the end of the file)", i); - goto return_bad; - } - big_size = code_sig->dataoff; - big_size += code_sig->datasize; - if(big_size > size){ - Mach_O_error(ofile, "truncated or malformed object " - "(dataoff field plus datasize field of " - "LC_CODE_SIGNATURE command %u extends past the end of " - "the file)", i); - goto return_bad; - } - if(check_overlaping_element(ofile, &elements, code_sig->dataoff, - code_sig->datasize, "code signature data") == CHECK_BAD) - goto return_bad; - break; + goto check_linkedit_data_command; - case LC_SEGMENT_SPLIT_INFO: - if(l.cmdsize < sizeof(struct linkedit_data_command)){ - Mach_O_error(ofile, "malformed object (LC_SEGMENT_SPLIT_" - "INFO cmdsize too small) in command %u", i); - goto return_bad; - } - if(split_info != NULL){ + case LC_FUNCTION_STARTS: + cmd_name = "LC_FUNCTION_STARTS"; + element_name = "function starts data"; + if(func_starts != NULL){ Mach_O_error(ofile, "malformed object (more than one " - "LC_SEGMENT_SPLIT_INFO command)"); - goto return_bad; - } - split_info = (struct linkedit_data_command *)lc; - if(swapped) - swap_linkedit_data_command(split_info, host_byte_sex); - if(split_info->cmdsize != sizeof(struct linkedit_data_command)){ - Mach_O_error(ofile, "malformed object (LC_SEGMENT_SPLIT_" - "INFO command %u has incorrect cmdsize)", i); - goto return_bad; - } - if(split_info->dataoff > size){ - Mach_O_error(ofile, "truncated or malformed object " - "(dataoff field of LC_SEGMENT_SPLIT_INFO command %u " - "extends past the end of the file)", i); + "%s command)", cmd_name); goto return_bad; } - big_size = split_info->dataoff; - big_size += split_info->datasize; - if(big_size > size){ - Mach_O_error(ofile, "truncated or malformed object " - "(dataoff field plus datasize field of LC_SEGMENT_" - "SPLIT_INFO command %u extends past the end of " - "the file)", i); + func_starts = (struct linkedit_data_command *)lc; + goto check_linkedit_data_command; + + case LC_DATA_IN_CODE: + cmd_name = "LC_DATA_IN_CODE"; + element_name = "date in code info"; + if(data_in_code != NULL){ + Mach_O_error(ofile, "malformed object (more than one " + "%s command)", cmd_name); goto return_bad; } - if((split_info->datasize % load_command_multiple) != 0){ - Mach_O_error(ofile, "truncated or malformed object " - "(datasize field of LC_SEGMENT_SPLIT_INFO command %u " - "is not a multple of %u)", i, load_command_multiple); + data_in_code = (struct linkedit_data_command *)lc; + goto check_linkedit_data_command; + + case LC_DYLIB_CODE_SIGN_DRS: + cmd_name = "LC_DYLIB_CODE_SIGN_DRS"; + element_name = "code signing RDs data"; + if(code_sign_drs != NULL){ + Mach_O_error(ofile, "malformed object (more than one " + "%s command)", cmd_name); goto return_bad; } - if(check_overlaping_element(ofile, &elements, - split_info->dataoff, split_info->datasize, - "split info data") == CHECK_BAD) - goto return_bad; - break; + code_sign_drs = (struct linkedit_data_command *)lc; + goto check_linkedit_data_command; - case LC_FUNCTION_STARTS: +check_linkedit_data_command: if(l.cmdsize < sizeof(struct linkedit_data_command)){ - Mach_O_error(ofile, "malformed object (LC_FUNCTION_STARTS " - "cmdsize too small) in command %u", i); - goto return_bad; - } - if(func_starts != NULL){ - Mach_O_error(ofile, "malformed object (more than one " - "LC_FUNCTION_STARTS command)"); + Mach_O_error(ofile, "malformed object (%s cmdsize too " + "small) in command %u", cmd_name, i); goto return_bad; } - func_starts = (struct linkedit_data_command *)lc; + linkedit_data = (struct linkedit_data_command *)lc; if(swapped) - swap_linkedit_data_command(func_starts, host_byte_sex); - if(func_starts->cmdsize != + swap_linkedit_data_command(linkedit_data, host_byte_sex); + if(linkedit_data->cmdsize != sizeof(struct linkedit_data_command)){ - Mach_O_error(ofile, "malformed object (LC_FUNCTION_STARTS " - "command %u has incorrect cmdsize)", i); + Mach_O_error(ofile, "malformed object (%s command %u has " + "incorrect cmdsize)", cmd_name, i); goto return_bad; } - if(func_starts->dataoff > size){ + if(linkedit_data->dataoff > size){ Mach_O_error(ofile, "truncated or malformed object " - "(dataoff field of LC_FUNCTION_STARTS command %u " - "extends past the end of the file)", i); + "(dataoff field of %s command %u extends past the end " + "of the file)", cmd_name, i); goto return_bad; } - big_size = func_starts->dataoff; - big_size += func_starts->datasize; + big_size = linkedit_data->dataoff; + big_size += linkedit_data->datasize; if(big_size > size){ Mach_O_error(ofile, "truncated or malformed object " "(dataoff field plus datasize field of " - "LC_FUNCTION_STARTS command %u extends past the end of " - "the file)", i); + "%s command %u extends past the end of " + "the file)", cmd_name, i); goto return_bad; } if(check_overlaping_element(ofile, &elements, - func_starts->dataoff, func_starts->datasize, - "function starts data") == CHECK_BAD) + linkedit_data->dataoff, linkedit_data->datasize, + element_name) == CHECK_BAD) goto return_bad; break; @@ -5745,6 +5715,30 @@ check_dylinker_command: goto return_bad; } break; + case LC_MAIN: + if(l.cmdsize < sizeof(struct entry_point_command)){ + Mach_O_error(ofile, "malformed object (LC_MAIN cmdsize " + "too small) in command %u", i); + goto return_bad; + } + ep = (struct entry_point_command *)lc; + if(swapped) + swap_entry_point_command(ep, host_byte_sex); + /* + * If we really wanted we could check that the entryoff field + * really is an offset into the __TEXT segment. But since it + * is not used here, we won't needlessly check it. + */ + break; + case LC_SOURCE_VERSION: + if(l.cmdsize < sizeof(struct source_version_command)){ + Mach_O_error(ofile, "malformed object (LC_SOURCE_VERSION " + "cmdsize too small) in command %u", i); + goto return_bad; + } + sv = (struct source_version_command *)lc; + if(swapped) + swap_source_version_command(sv, host_byte_sex); case LC_IDENT: if(l.cmdsize < sizeof(struct ident_command)){ Mach_O_error(ofile, "malformed object (LC_IDENT cmdsize " diff --git a/libstuff/swap_headers.c b/libstuff/swap_headers.c index 1213978..ba2ff6b 100644 --- a/libstuff/swap_headers.c +++ b/libstuff/swap_headers.c @@ -75,6 +75,8 @@ struct load_command *load_commands) struct fvmlib_command *fl; struct thread_command *ut; struct ident_command *id; + struct entry_point_command *ep; + struct source_version_command *sv; struct dylib_command *dl; struct sub_framework_command *sub; struct sub_umbrella_command *usub; @@ -961,6 +963,30 @@ check_dylinker_command: cpusubtype, ut->cmd == LC_UNIXTHREAD ? "LC_UNIXTHREAD" : "LC_THREAD", i); return(FALSE); + + case LC_MAIN: + ep = (struct entry_point_command *)lc; + if((char *)ep + ep->cmdsize > + (char *)load_commands + sizeofcmds){ + error("in swap_object_headers(): truncated or malformed " + "load commands (cmdsize field of LC_MAIN command %lu " + "extends past the end of the load commands)", i); + return(FALSE); + } + break; + + case LC_SOURCE_VERSION: + sv = (struct source_version_command *)lc; + if((char *)sv + sv->cmdsize > + (char *)load_commands + sizeofcmds){ + error("in swap_object_headers(): truncated or malformed " + "load commands (cmdsize field of LC_SOURCE_VERSION " + "command %lu extends past the end of the load " + "commands)", i); + return(FALSE); + } + break; + case LC_IDENT: id = (struct ident_command *)lc; if((char *)id + id->cmdsize > @@ -1051,6 +1077,26 @@ check_dylinker_command: } break; + case LC_DATA_IN_CODE: + ld = (struct linkedit_data_command *)lc; + if(ld->cmdsize != sizeof(struct linkedit_data_command)){ + error("in swap_object_headers(): malformed load commands " + "(LC_DATA_IN_CODE command %lu has incorrect " + "cmdsize", i); + return(FALSE); + } + break; + + case LC_DYLIB_CODE_SIGN_DRS: + ld = (struct linkedit_data_command *)lc; + if(ld->cmdsize != sizeof(struct linkedit_data_command)){ + error("in swap_object_headers(): malformed load commands " + "(LC_DYLIB_CODE_SIGN_DRS command %lu has incorrect " + "cmdsize", i); + return(FALSE); + } + break; + case LC_VERSION_MIN_MACOSX: vc = (struct version_min_command *)lc; if(vc->cmdsize != sizeof(struct version_min_command)){ @@ -1531,6 +1577,16 @@ check_dylinker_command: } break; + case LC_MAIN: + ep = (struct entry_point_command *)lc; + swap_entry_point_command(ep, target_byte_sex); + break; + + case LC_SOURCE_VERSION: + sv = (struct source_version_command *)lc; + swap_source_version_command(sv, target_byte_sex); + break; + case LC_IDENT: id = (struct ident_command *)lc; swap_ident_command(id, target_byte_sex); @@ -1564,6 +1620,8 @@ check_dylinker_command: case LC_CODE_SIGNATURE: case LC_SEGMENT_SPLIT_INFO: case LC_FUNCTION_STARTS: + case LC_DATA_IN_CODE: + case LC_DYLIB_CODE_SIGN_DRS: ld = (struct linkedit_data_command *)lc; swap_linkedit_data_command(ld, target_byte_sex); break; diff --git a/libstuff/writeout.c b/libstuff/writeout.c index 2638d9c..82cf317 100644 --- a/libstuff/writeout.c +++ b/libstuff/writeout.c @@ -761,6 +761,18 @@ struct object *object) object->output_func_start_info_data_size); *size += object->output_func_start_info_data_size; } + if(object->output_data_in_code_info_data_size != 0){ + if(object->output_data_in_code_info_data != NULL) + memcpy(p + *size, object->output_data_in_code_info_data, + object->output_data_in_code_info_data_size); + *size += object->output_data_in_code_info_data_size; + } + if(object->output_code_sign_drs_info_data_size != 0){ + if(object->output_code_sign_drs_info_data != NULL) + memcpy(p + *size, object->output_code_sign_drs_info_data, + object->output_code_sign_drs_info_data_size); + *size += object->output_code_sign_drs_info_data_size; + } if(object->mh != NULL){ memcpy(p + *size, object->output_symbols, object->output_nsymbols * sizeof(struct nlist)); @@ -819,6 +831,18 @@ struct object *object) } } else{ + if(object->output_func_start_info_data_size != 0){ + if(object->output_func_start_info_data != NULL) + memcpy(p + *size, object->output_func_start_info_data, + object->output_func_start_info_data_size); + *size += object->output_func_start_info_data_size; + } + if(object->output_data_in_code_info_data_size != 0){ + if(object->output_data_in_code_info_data != NULL) + memcpy(p + *size, object->output_data_in_code_info_data, + object->output_data_in_code_info_data_size); + *size += object->output_data_in_code_info_data_size; + } if(object->mh != NULL){ memcpy(p + *size, object->output_symbols, object->output_nsymbols * sizeof(struct nlist)); diff --git a/strip.c b/strip.c index e18560d..c32f5c8 100644 --- a/strip.c +++ b/strip.c @@ -346,6 +346,10 @@ static int cmp_bsearch_global_64( const struct nlist_64 **sym); #endif /* NMEDIT */ +/* apple_version is created by the libstuff/Makefile */ +extern char apple_version[]; +char *version = apple_version; + int main( int argc, @@ -1238,26 +1242,19 @@ struct object *object) if(no_uuid == TRUE) strip_LC_UUID_commands(arch, member, object); #endif /* !defined(NMEDIT) */ - if(object->mh != NULL) - object->output_sym_info_size = - new_nsyms * sizeof(struct nlist) + - new_strsize; - else - object->output_sym_info_size = - new_nsyms * sizeof(struct nlist_64) + - new_strsize; - - object->st->nsyms = new_nsyms; - object->st->strsize = new_strsize; - - if(object->mh != NULL) - object->output_symbols = new_symbols; - else - object->output_symbols64 = new_symbols64; - object->output_nsymbols = new_nsyms; - object->output_strings = new_strings; - object->output_strings_size = new_strsize; - + /* + * The parts that make up output_sym_info_size must be added up in + * the output order so that when the sizes of things are rounded up + * before parts that must be aligned the final output_sym_info_size + * is correct. + * + * Also the parts that make up input_sym_info_size must be added up + * in the same way. And must be done here as the input file may + * have been changed to and "ld -r" file and may not be the + * the original input file. + */ + object->output_sym_info_size = 0; + object->input_sym_info_size = 0; if(object->dyld_info != NULL){ /* there are five parts to the dyld info, but strip does not alter them, so copy as a block */ @@ -1301,19 +1298,164 @@ struct object *object) "-exported_symbols_list at link time when " "building: "); } + object->input_sym_info_size += object->dyld_info->rebase_size + + object->dyld_info->bind_size + + object->dyld_info->weak_bind_size + + object->dyld_info->lazy_bind_size + + object->dyld_info->export_size; + } + + if(object->dyst != NULL){ +#ifndef NMEDIT + /* + * When stripping out the section contents to create a + * dynamic library stub the relocation info also gets + * stripped. + */ + if(!cflag) +#endif /* !(NMEDIT) */ + { + object->output_sym_info_size += + object->dyst->nlocrel * sizeof(struct relocation_info); + } + object->input_sym_info_size += + object->dyst->nlocrel * sizeof(struct relocation_info); } + if(object->split_info_cmd != NULL){ object->output_split_info_data = object->object_addr + object->split_info_cmd->dataoff; object->output_split_info_data_size = object->split_info_cmd->datasize; + object->input_sym_info_size += object->split_info_cmd->datasize; + object->output_sym_info_size += + object->split_info_cmd->datasize; } + if(object->func_starts_info_cmd != NULL){ object->output_func_start_info_data = object->object_addr + object->func_starts_info_cmd->dataoff; object->output_func_start_info_data_size = object->func_starts_info_cmd->datasize; + object->input_sym_info_size += + object->func_starts_info_cmd->datasize; + object->output_sym_info_size += + object->func_starts_info_cmd->datasize; + } + + if(object->data_in_code_cmd != NULL){ + object->output_data_in_code_info_data = object->object_addr + + object->data_in_code_cmd->dataoff; + object->output_data_in_code_info_data_size = + object->data_in_code_cmd->datasize; + object->input_sym_info_size += + object->data_in_code_cmd->datasize; + object->output_sym_info_size += + object->data_in_code_cmd->datasize; + } + + if(object->code_sign_drs_cmd != NULL){ + object->output_code_sign_drs_info_data = object->object_addr + + object->code_sign_drs_cmd->dataoff; + object->output_code_sign_drs_info_data_size = + object->code_sign_drs_cmd->datasize; + object->input_sym_info_size += + object->code_sign_drs_cmd->datasize; + object->output_sym_info_size += + object->code_sign_drs_cmd->datasize; + } + + if(object->mh != NULL){ + object->input_sym_info_size += nsyms * sizeof(struct nlist); + object->output_symbols = new_symbols; + object->output_sym_info_size += + new_nsyms * sizeof(struct nlist); + } + else{ + object->input_sym_info_size += nsyms * sizeof(struct nlist_64); + object->output_symbols64 = new_symbols64; + object->output_sym_info_size += + new_nsyms * sizeof(struct nlist_64); + } + object->output_nsymbols = new_nsyms; + object->st->nsyms = new_nsyms; + + if(object->hints_cmd != NULL){ + object->input_sym_info_size += + object->hints_cmd->nhints * + sizeof(struct twolevel_hint); + object->output_sym_info_size += + object->hints_cmd->nhints * + sizeof(struct twolevel_hint); + } + + if(object->dyst != NULL){ +#ifndef NMEDIT + /* + * When stripping out the section contents to create a + * dynamic library stub the relocation info also gets + * stripped. + */ + if(!cflag) +#endif /* !(NMEDIT) */ + { + object->output_sym_info_size += + object->dyst->nextrel * sizeof(struct relocation_info); + } + object->input_sym_info_size += + object->dyst->nextrel * sizeof(struct relocation_info); } + + if(object->dyst != NULL){ + object->output_sym_info_size += + object->dyst->nindirectsyms * sizeof(uint32_t) + + object->input_indirectsym_pad; + if(object->mh != NULL){ + object->input_sym_info_size += + object->dyst->nindirectsyms * sizeof(uint32_t); + } + else{ + object->input_sym_info_size += + object->dyst->nindirectsyms * sizeof(uint32_t) + + object->input_indirectsym_pad; + } + } + + if(object->dyst != NULL){ + object->output_sym_info_size += + new_ntoc * sizeof(struct dylib_table_of_contents); + object->input_sym_info_size += + object->dyst->ntoc * sizeof(struct dylib_table_of_contents); + } + + if(object->dyst != NULL){ + if(object->mh != NULL){ + object->output_sym_info_size += + object->dyst->nmodtab * sizeof(struct dylib_module); + object->input_sym_info_size += + object->dyst->nmodtab * sizeof(struct dylib_module); + } + else{ + object->output_sym_info_size += + object->dyst->nmodtab * sizeof(struct dylib_module_64); + object->input_sym_info_size += + object->dyst->nmodtab * sizeof(struct dylib_module_64); + } + } + + if(object->dyst != NULL){ + object->output_sym_info_size += + new_nextrefsyms * sizeof(struct dylib_reference); + object->input_sym_info_size += + object->dyst->nextrefsyms * sizeof(struct dylib_reference); + } + + object->output_strings = new_strings; + object->output_strings_size = new_strsize; + object->output_sym_info_size += new_strsize; + object->input_sym_info_size += strsize; + object->st->strsize = new_strsize; + if(object->code_sig_cmd != NULL){ #ifndef NMEDIT if(!cflag) @@ -1324,6 +1466,22 @@ struct object *object) object->output_code_sig_data_size = object->code_sig_cmd->datasize; } + object->input_sym_info_size = + rnd(object->input_sym_info_size, 16); + object->input_sym_info_size += + object->code_sig_cmd->datasize; +#ifndef NMEDIT + if(cflag){ + strip_LC_CODE_SIGNATURE_commands(arch, member, object); + } + else +#endif /* !(NMEDIT) */ + { + object->output_sym_info_size = + rnd(object->output_sym_info_size, 16); + object->output_sym_info_size += + object->code_sig_cmd->datasize; + } } if(object->dyst != NULL){ @@ -1382,94 +1540,6 @@ struct object *object) object->object_byte_sex); } } - if(object->dyld_info != NULL){ - object->input_sym_info_size += object->dyld_info->rebase_size - + object->dyld_info->bind_size - + object->dyld_info->weak_bind_size - + object->dyld_info->lazy_bind_size - + object->dyld_info->export_size; - } - object->input_sym_info_size += - object->dyst->nlocrel * sizeof(struct relocation_info) + - object->dyst->nextrel * sizeof(struct relocation_info) + - object->dyst->ntoc * sizeof(struct dylib_table_of_contents)+ - object->dyst->nextrefsyms * sizeof(struct dylib_reference); - if(object->mh != NULL){ - object->input_sym_info_size += - object->dyst->nmodtab * sizeof(struct dylib_module) + - object->dyst->nindirectsyms * sizeof(uint32_t); - } - else{ - object->input_sym_info_size += - object->dyst->nmodtab * sizeof(struct dylib_module_64) + - object->dyst->nindirectsyms * sizeof(uint32_t) + - object->input_indirectsym_pad; - } -#ifndef NMEDIT - /* - * When stripping out the section contents to create a - * dynamic library stub the relocation info also gets - * stripped. - */ - if(!cflag) -#endif /* !(NMEDIT) */ - { - object->output_sym_info_size += - object->dyst->nlocrel * sizeof(struct relocation_info) + - object->dyst->nextrel * sizeof(struct relocation_info); - } - object->output_sym_info_size += - new_ntoc * sizeof(struct dylib_table_of_contents)+ - new_nextrefsyms * sizeof(struct dylib_reference) + - object->dyst->nindirectsyms * sizeof(uint32_t) + - object->input_indirectsym_pad; - if(object->mh != NULL){ - object->output_sym_info_size += - object->dyst->nmodtab * sizeof(struct dylib_module); - } - else{ - object->output_sym_info_size += - object->dyst->nmodtab * sizeof(struct dylib_module_64); - } - if(object->hints_cmd != NULL){ - object->input_sym_info_size += - object->hints_cmd->nhints * - sizeof(struct twolevel_hint); - object->output_sym_info_size += - object->hints_cmd->nhints * - sizeof(struct twolevel_hint); - } - if(object->split_info_cmd != NULL){ - object->input_sym_info_size += - object->split_info_cmd->datasize; - object->output_sym_info_size += - object->split_info_cmd->datasize; - } - if(object->func_starts_info_cmd != NULL){ - object->input_sym_info_size += - object->func_starts_info_cmd->datasize; - object->output_sym_info_size += - object->func_starts_info_cmd->datasize; - } - if(object->code_sig_cmd != NULL){ - object->input_sym_info_size = - rnd(object->input_sym_info_size, 16); - object->input_sym_info_size += - object->code_sig_cmd->datasize; -#ifndef NMEDIT - if(cflag){ - strip_LC_CODE_SIGNATURE_commands(arch, member, object); - } - else -#endif /* !(NMEDIT) */ - { - object->output_sym_info_size = - rnd(object->output_sym_info_size, 16); - object->output_sym_info_size += - object->code_sig_cmd->datasize; - } - } - object->dyst->ntoc = new_ntoc; object->dyst->nextrefsyms = new_nextrefsyms; @@ -1532,6 +1602,16 @@ struct object *object) offset += object->func_starts_info_cmd->datasize; } + if(object->data_in_code_cmd != NULL){ + object->data_in_code_cmd->dataoff = offset; + offset += object->data_in_code_cmd->datasize; + } + + if(object->code_sign_drs_cmd != NULL){ + object->code_sign_drs_cmd->dataoff = offset; + offset += object->code_sign_drs_cmd->datasize; + } + if(object->st->nsyms != 0){ object->st->symoff = offset; if(object->mh != NULL) @@ -2308,8 +2388,8 @@ enum byte_sex host_byte_sex) n_type = symbols64[index].n_type; n_strx = symbols64[index].n_un.n_strx; } - if((n_type && N_TYPE) != N_UNDF && - (n_type && N_TYPE) != N_PBUD && + if((n_type & N_TYPE) != N_UNDF && + (n_type & N_TYPE) != N_PBUD && section_type == S_NON_LAZY_SYMBOL_POINTERS){ object->output_indirect_symtab[reserved1 + k] = INDIRECT_SYMBOL_LOCAL; @@ -2531,19 +2611,7 @@ uint32_t nextrefsyms) } lc = (struct load_command *)((char *)lc + lc->cmdsize); } - /* - * Because of the bugs in ld(1) for: - * radr://5675774 ld64 should preserve JBSR relocations without - * -static - * radr://5658046 cctools-679 creates scattered relocations in - * __TEXT,__const section in kexts, which breaks - * kexts built for older systems - * we can't use ld -r to strip dwarf info in 32-bit objects until - * these are fixed. But if the user as specified the -l flag then - * go ahead and do it and the user will have to be aware of these - * bugs. - */ - if((lflag == TRUE && has_dwarf == TRUE) || object->mh64 != NULL) + if(has_dwarf == TRUE) make_ld_r_object(arch, member, object); } /* @@ -4044,6 +4112,14 @@ struct object *object) object->func_starts_info_cmd = (struct linkedit_data_command *)lc1; break; + case LC_DATA_IN_CODE: + object->data_in_code_cmd = + (struct linkedit_data_command *)lc1; + break; + case LC_DYLIB_CODE_SIGN_DRS: + object->code_sign_drs_cmd = + (struct linkedit_data_command *)lc1; + break; case LC_CODE_SIGNATURE: object->code_sig_cmd = (struct linkedit_data_command *)lc1; break; @@ -4157,6 +4233,14 @@ struct object *object) object->func_starts_info_cmd = (struct linkedit_data_command *)lc1; break; + case LC_DATA_IN_CODE: + object->data_in_code_cmd = + (struct linkedit_data_command *)lc1; + break; + case LC_DYLIB_CODE_SIGN_DRS: + object->code_sign_drs_cmd = + (struct linkedit_data_command *)lc1; + break; } lc1 = (struct load_command *)((char *)lc1 + lc1->cmdsize); } diff --git a/tease.c b/tease.c index 8ac9bde..416ab4f 100644 --- a/tease.c +++ b/tease.c @@ -351,6 +351,10 @@ static int cmp_bsearch_global_64( const struct nlist_64 **sym); #endif /* NMEDIT */ +/* apple_version is created by the libstuff/Makefile */ +extern char apple_version[]; +char *version = apple_version; + int main( int argc, @@ -1255,26 +1259,19 @@ struct object *object) if(no_uuid == TRUE) strip_LC_UUID_commands(arch, member, object); #endif /* !defined(NMEDIT) */ - if(object->mh != NULL) - object->output_sym_info_size = - new_nsyms * sizeof(struct nlist) + - new_strsize; - else - object->output_sym_info_size = - new_nsyms * sizeof(struct nlist_64) + - new_strsize; - - object->st->nsyms = new_nsyms; - object->st->strsize = new_strsize; - - if(object->mh != NULL) - object->output_symbols = new_symbols; - else - object->output_symbols64 = new_symbols64; - object->output_nsymbols = new_nsyms; - object->output_strings = new_strings; - object->output_strings_size = new_strsize; - + /* + * The parts that make up output_sym_info_size must be added up in + * the output order so that when the sizes of things are rounded up + * before parts that must be aligned the final output_sym_info_size + * is correct. + * + * Also the parts that make up input_sym_info_size must be added up + * in the same way. And must be done here as the input file may + * have been changed to and "ld -r" file and may not be the + * the original input file. + */ + object->output_sym_info_size = 0; + object->input_sym_info_size = 0; if(object->dyld_info != NULL){ /* there are five parts to the dyld info, but strip does not alter them, so copy as a block */ @@ -1318,19 +1315,164 @@ struct object *object) "-exported_symbols_list at link time when " "building: "); } + object->input_sym_info_size += object->dyld_info->rebase_size + + object->dyld_info->bind_size + + object->dyld_info->weak_bind_size + + object->dyld_info->lazy_bind_size + + object->dyld_info->export_size; } + + if(object->dyst != NULL){ +#ifndef NMEDIT + /* + * When stripping out the section contents to create a + * dynamic library stub the relocation info also gets + * stripped. + */ + if(!cflag) +#endif /* !(NMEDIT) */ + { + object->output_sym_info_size += + object->dyst->nlocrel * sizeof(struct relocation_info); + } + object->input_sym_info_size += + object->dyst->nlocrel * sizeof(struct relocation_info); + } + if(object->split_info_cmd != NULL){ object->output_split_info_data = object->object_addr + object->split_info_cmd->dataoff; object->output_split_info_data_size = object->split_info_cmd->datasize; + object->input_sym_info_size += object->split_info_cmd->datasize; + object->output_sym_info_size += + object->split_info_cmd->datasize; } + if(object->func_starts_info_cmd != NULL){ object->output_func_start_info_data = object->object_addr + object->func_starts_info_cmd->dataoff; object->output_func_start_info_data_size = object->func_starts_info_cmd->datasize; + object->input_sym_info_size += + object->func_starts_info_cmd->datasize; + object->output_sym_info_size += + object->func_starts_info_cmd->datasize; + } + + if(object->data_in_code_cmd != NULL){ + object->output_data_in_code_info_data = object->object_addr + + object->data_in_code_cmd->dataoff; + object->output_data_in_code_info_data_size = + object->data_in_code_cmd->datasize; + object->input_sym_info_size += + object->data_in_code_cmd->datasize; + object->output_sym_info_size += + object->data_in_code_cmd->datasize; + } + + if(object->code_sign_drs_cmd != NULL){ + object->output_code_sign_drs_info_data = object->object_addr + + object->code_sign_drs_cmd->dataoff; + object->output_code_sign_drs_info_data_size = + object->code_sign_drs_cmd->datasize; + object->input_sym_info_size += + object->code_sign_drs_cmd->datasize; + object->output_sym_info_size += + object->code_sign_drs_cmd->datasize; + } + + if(object->mh != NULL){ + object->input_sym_info_size += nsyms * sizeof(struct nlist); + object->output_symbols = new_symbols; + object->output_sym_info_size += + new_nsyms * sizeof(struct nlist); } + else{ + object->input_sym_info_size += nsyms * sizeof(struct nlist_64); + object->output_symbols64 = new_symbols64; + object->output_sym_info_size += + new_nsyms * sizeof(struct nlist_64); + } + object->output_nsymbols = new_nsyms; + object->st->nsyms = new_nsyms; + + if(object->hints_cmd != NULL){ + object->input_sym_info_size += + object->hints_cmd->nhints * + sizeof(struct twolevel_hint); + object->output_sym_info_size += + object->hints_cmd->nhints * + sizeof(struct twolevel_hint); + } + + if(object->dyst != NULL){ +#ifndef NMEDIT + /* + * When stripping out the section contents to create a + * dynamic library stub the relocation info also gets + * stripped. + */ + if(!cflag) +#endif /* !(NMEDIT) */ + { + object->output_sym_info_size += + object->dyst->nextrel * sizeof(struct relocation_info); + } + object->input_sym_info_size += + object->dyst->nextrel * sizeof(struct relocation_info); + } + + if(object->dyst != NULL){ + object->output_sym_info_size += + object->dyst->nindirectsyms * sizeof(uint32_t) + + object->input_indirectsym_pad; + if(object->mh != NULL){ + object->input_sym_info_size += + object->dyst->nindirectsyms * sizeof(uint32_t); + } + else{ + object->input_sym_info_size += + object->dyst->nindirectsyms * sizeof(uint32_t) + + object->input_indirectsym_pad; + } + } + + if(object->dyst != NULL){ + object->output_sym_info_size += + new_ntoc * sizeof(struct dylib_table_of_contents); + object->input_sym_info_size += + object->dyst->ntoc * sizeof(struct dylib_table_of_contents); + } + + if(object->dyst != NULL){ + if(object->mh != NULL){ + object->output_sym_info_size += + object->dyst->nmodtab * sizeof(struct dylib_module); + object->input_sym_info_size += + object->dyst->nmodtab * sizeof(struct dylib_module); + } + else{ + object->output_sym_info_size += + object->dyst->nmodtab * sizeof(struct dylib_module_64); + object->input_sym_info_size += + object->dyst->nmodtab * sizeof(struct dylib_module_64); + } + } + + if(object->dyst != NULL){ + object->output_sym_info_size += + new_nextrefsyms * sizeof(struct dylib_reference); + object->input_sym_info_size += + object->dyst->nextrefsyms * sizeof(struct dylib_reference); + } + + object->output_strings = new_strings; + object->output_strings_size = new_strsize; + object->output_sym_info_size += new_strsize; + object->input_sym_info_size += strsize; + object->st->strsize = new_strsize; + if(object->code_sig_cmd != NULL){ #ifndef NMEDIT if(!cflag && !no_code_signature) @@ -1341,6 +1483,22 @@ struct object *object) object->output_code_sig_data_size = object->code_sig_cmd->datasize; } + object->input_sym_info_size = + rnd(object->input_sym_info_size, 16); + object->input_sym_info_size += + object->code_sig_cmd->datasize; +#ifndef NMEDIT + if(cflag || no_code_signature){ + strip_LC_CODE_SIGNATURE_commands(arch, member, object); + } + else +#endif /* !(NMEDIT) */ + { + object->output_sym_info_size = + rnd(object->output_sym_info_size, 16); + object->output_sym_info_size += + object->code_sig_cmd->datasize; + } } if(object->dyst != NULL){ @@ -1399,94 +1557,6 @@ struct object *object) object->object_byte_sex); } } - if(object->dyld_info != NULL){ - object->input_sym_info_size += object->dyld_info->rebase_size - + object->dyld_info->bind_size - + object->dyld_info->weak_bind_size - + object->dyld_info->lazy_bind_size - + object->dyld_info->export_size; - } - object->input_sym_info_size += - object->dyst->nlocrel * sizeof(struct relocation_info) + - object->dyst->nextrel * sizeof(struct relocation_info) + - object->dyst->ntoc * sizeof(struct dylib_table_of_contents)+ - object->dyst->nextrefsyms * sizeof(struct dylib_reference); - if(object->mh != NULL){ - object->input_sym_info_size += - object->dyst->nmodtab * sizeof(struct dylib_module) + - object->dyst->nindirectsyms * sizeof(uint32_t); - } - else{ - object->input_sym_info_size += - object->dyst->nmodtab * sizeof(struct dylib_module_64) + - object->dyst->nindirectsyms * sizeof(uint32_t) + - object->input_indirectsym_pad; - } -#ifndef NMEDIT - /* - * When stripping out the section contents to create a - * dynamic library stub the relocation info also gets - * stripped. - */ - if(!cflag) -#endif /* !(NMEDIT) */ - { - object->output_sym_info_size += - object->dyst->nlocrel * sizeof(struct relocation_info) + - object->dyst->nextrel * sizeof(struct relocation_info); - } - object->output_sym_info_size += - new_ntoc * sizeof(struct dylib_table_of_contents)+ - new_nextrefsyms * sizeof(struct dylib_reference) + - object->dyst->nindirectsyms * sizeof(uint32_t) + - object->input_indirectsym_pad; - if(object->mh != NULL){ - object->output_sym_info_size += - object->dyst->nmodtab * sizeof(struct dylib_module); - } - else{ - object->output_sym_info_size += - object->dyst->nmodtab * sizeof(struct dylib_module_64); - } - if(object->hints_cmd != NULL){ - object->input_sym_info_size += - object->hints_cmd->nhints * - sizeof(struct twolevel_hint); - object->output_sym_info_size += - object->hints_cmd->nhints * - sizeof(struct twolevel_hint); - } - if(object->split_info_cmd != NULL){ - object->input_sym_info_size += - object->split_info_cmd->datasize; - object->output_sym_info_size += - object->split_info_cmd->datasize; - } - if(object->func_starts_info_cmd != NULL){ - object->input_sym_info_size += - object->func_starts_info_cmd->datasize; - object->output_sym_info_size += - object->func_starts_info_cmd->datasize; - } - if(object->code_sig_cmd != NULL){ - object->input_sym_info_size = - rnd(object->input_sym_info_size, 16); - object->input_sym_info_size += - object->code_sig_cmd->datasize; -#ifndef NMEDIT - if(cflag || no_code_signature){ - strip_LC_CODE_SIGNATURE_commands(arch, member, object); - } - else -#endif /* !(NMEDIT) */ - { - object->output_sym_info_size = - rnd(object->output_sym_info_size, 16); - object->output_sym_info_size += - object->code_sig_cmd->datasize; - } - } - object->dyst->ntoc = new_ntoc; object->dyst->nextrefsyms = new_nextrefsyms; @@ -1549,6 +1619,16 @@ struct object *object) offset += object->func_starts_info_cmd->datasize; } + if(object->data_in_code_cmd != NULL){ + object->data_in_code_cmd->dataoff = offset; + offset += object->data_in_code_cmd->datasize; + } + + if(object->code_sign_drs_cmd != NULL){ + object->code_sign_drs_cmd->dataoff = offset; + offset += object->code_sign_drs_cmd->datasize; + } + if(object->st->nsyms != 0){ object->st->symoff = offset; if(object->mh != NULL) @@ -2325,8 +2405,8 @@ enum byte_sex host_byte_sex) n_type = symbols64[index].n_type; n_strx = symbols64[index].n_un.n_strx; } - if((n_type && N_TYPE) != N_UNDF && - (n_type && N_TYPE) != N_PBUD && + if((n_type & N_TYPE) != N_UNDF && + (n_type & N_TYPE) != N_PBUD && section_type == S_NON_LAZY_SYMBOL_POINTERS){ object->output_indirect_symtab[reserved1 + k] = INDIRECT_SYMBOL_LOCAL; @@ -2549,19 +2629,7 @@ uint32_t nextrefsyms) } lc = (struct load_command *)((char *)lc + lc->cmdsize); } - /* - * Because of the bugs in ld(1) for: - * radr://5675774 ld64 should preserve JBSR relocations without - * -static - * radr://5658046 cctools-679 creates scattered relocations in - * __TEXT,__const section in kexts, which breaks - * kexts built for older systems - * we can't use ld -r to strip dwarf info in 32-bit objects until - * these are fixed. But if the user as specified the -l flag then - * go ahead and do it and the user will have to be aware of these - * bugs. - */ - if((lflag == TRUE && has_dwarf == TRUE) || object->mh64 != NULL) + if(has_dwarf == TRUE) make_ld_r_object(arch, member, object); } /* @@ -4087,6 +4155,14 @@ struct object *object) object->func_starts_info_cmd = (struct linkedit_data_command *)lc1; break; + case LC_DATA_IN_CODE: + object->data_in_code_cmd = + (struct linkedit_data_command *)lc1; + break; + case LC_DYLIB_CODE_SIGN_DRS: + object->code_sign_drs_cmd = + (struct linkedit_data_command *)lc1; + break; case LC_CODE_SIGNATURE: object->code_sig_cmd = (struct linkedit_data_command *)lc1; break; @@ -4200,6 +4276,17 @@ struct object *object) object->func_starts_info_cmd = (struct linkedit_data_command *)lc1; break; + case LC_DATA_IN_CODE: + object->data_in_code_cmd = + (struct linkedit_data_command *)lc1; + break; + case LC_DYLIB_CODE_SIGN_DRS: + object->code_sign_drs_cmd = + (struct linkedit_data_command *)lc1; + break; + case LC_DYLD_INFO_ONLY: + case LC_DYLD_INFO: + object->dyld_info = (struct dyld_info_command *)lc1; } lc1 = (struct load_command *)((char *)lc1 + lc1->cmdsize); } @@ -4211,12 +4298,12 @@ struct object *object) * already reduce the object size by the size of the section * contents including the padding after the load commands. So here * we need to further reduce it by the load command for the - * LC_CODE_SIGNATURE (a struct linkedit_data_command) we are + * LC_CODE_SIGNATURE (a struct linkedit_data_command) we are * removing. */ object->object_size -= sizeof(struct linkedit_data_command); /* - * Then this size minus the size of the input symbolic information + * Then this size minus the size of the input symbolic information * is what is copied out from the file by writeout(). Which in this * case is just the new headers. */ diff --git a/version.c b/version.c new file mode 100644 index 0000000..5d7aa39 --- /dev/null +++ b/version.c @@ -0,0 +1,4 @@ +extern const char apple_version[]; +const char apple_version[] = +"@(#)$PROGRAM: striptease PROJECT: cctools-822 $" +; -- 2.11.4.GIT