merge cctools-862

This commit is contained in:
Thomas Pöchtrager 2014-11-21 22:10:09 +01:00
parent 400835f16c
commit fdff001d40
22 changed files with 478 additions and 123 deletions

View File

@ -1,4 +1,4 @@
AC_INIT([cctools], [855], [t.poechtrager@gmail.com])
AC_INIT([cctools], [862], [t.poechtrager@gmail.com])
AC_CANONICAL_BUILD
AC_CANONICAL_HOST

View File

@ -2497,14 +2497,15 @@ struct arch *arch)
if (debug_uuid != NULL) {
string_to_uuid (debug_uuid, uuid->uuid);
}
mdi->uuid[0] = uuid->uuid[0];
mdi->uuid[1] = uuid->uuid[1];
mdi->uuid[2] = uuid->uuid[2];
mdi->uuid[3] = uuid->uuid[3];
mdi->uuid[4] = uuid->uuid[4];
mdi->uuid[5] = uuid->uuid[5];
mdi->uuid[6] = uuid->uuid[6];
mdi->uuid[7] = uuid->uuid[7];
/* Swizzle UUID to match EFI GUID definition */
mdi->uuid[0] = uuid->uuid[3];
mdi->uuid[1] = uuid->uuid[2];
mdi->uuid[2] = uuid->uuid[1];
mdi->uuid[3] = uuid->uuid[0];
mdi->uuid[4] = uuid->uuid[5];
mdi->uuid[5] = uuid->uuid[4];
mdi->uuid[6] = uuid->uuid[7];
mdi->uuid[7] = uuid->uuid[6];
mdi->uuid[8] = uuid->uuid[8];
mdi->uuid[9] = uuid->uuid[9];
mdi->uuid[10] = uuid->uuid[10];
@ -2578,13 +2579,9 @@ uint8_t *uuid)
{
uint8_t count;
/*
* scanned bytewise to ensure correct endianness of fields
*/
count = sscanf (string, UUID_FORMAT_STRING,
&uuid[3], &uuid[2], &uuid[1], &uuid[0],
&uuid[5], &uuid[4],
&uuid[7], &uuid[6],
&uuid[0], &uuid[1], &uuid[2], &uuid[3],
&uuid[4], &uuid[5], &uuid[6], &uuid[7],
&uuid[8], &uuid[9], &uuid[10], &uuid[11],
&uuid[12], &uuid[13], &uuid[14], &uuid[15]);

View File

@ -202,6 +202,12 @@ int LLVMSetDisasmOptions(LLVMDisasmContextRef DC, uint64_t Options);
#define LLVMDisassembler_Option_UseMarkup 1
/* The option to print immediates as hex. */
#define LLVMDisassembler_Option_PrintImmHex 2
/* The option use the other assembler printer variant */
#define LLVMDisassembler_Option_AsmPrinterVariant 4
/* The option to set comment on instructions */
#define LLVMDisassembler_Option_SetInstrComments 8
/* The option to print latency information alongside instructions */
#define LLVMDisassembler_Option_PrintLatency 16
/**
* Dispose of a disassembler context.

View File

@ -207,6 +207,9 @@ struct mach_header_64 {
require it. Only used in MH_EXECUTE
filetypes. */
#define MH_APP_EXTENSION_SAFE 0x02000000 /* The code was linked for use in an
application extension. */
/*
* The load commands directly follow the mach_header. The total size of all
* of the commands is given by the sizeofcmds field in the mach_header. All

View File

@ -296,6 +296,12 @@ struct nlist_64 {
*/
#define N_SYMBOL_RESOLVER 0x0100
/*
* The N_ALT_ENTRY bit of the n_desc field indicates that the
* symbol is pinned to the previous content.
*/
#define N_ALT_ENTRY 0x0200
#ifndef __STRICT_BSD__
#ifdef __cplusplus
extern "C" {

View File

@ -26,4 +26,7 @@ __private_extern__ int llvm_disasm_set_options(
LLVMDisasmContextRef DC,
uint64_t Options);
__private_extern__ const char *llvm_disasm_version_string(
void);
#endif /* _STUFF_LLVM_H_ */

View File

@ -357,6 +357,13 @@ struct object *object)
order_error(arch, member, "dyld_info "
"out of place");
}
else if(object->dyld_info->export_off != 0){
if(object->dyld_info->export_off != offset &&
object->dyld_info->weak_bind_size != 0 &&
object->dyld_info->lazy_bind_size != 0)
order_error(arch, member, "dyld_info "
"out of place");
}
/* update offset to end of dyld_info contents */
if (object->dyld_info->export_size != 0)
offset = object->dyld_info->export_off +
@ -382,17 +389,20 @@ struct object *object)
sizeof(struct relocation_info);
}
if(object->split_info_cmd != NULL){
if(object->split_info_cmd->dataoff != offset)
if(object->split_info_cmd->dataoff != 0 &&
object->split_info_cmd->dataoff != offset)
order_error(arch, member, "split info data out of place");
offset += object->split_info_cmd->datasize;
}
if(object->func_starts_info_cmd != NULL){
if(object->func_starts_info_cmd->dataoff != offset)
if(object->func_starts_info_cmd->dataoff != 0 &&
object->func_starts_info_cmd->dataoff != offset)
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)
if(object->data_in_code_cmd->dataoff != 0 &&
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;
}
@ -608,9 +618,10 @@ struct object *object)
* at the end of the object file change the object_size to be
* the end of the string table here. This could be done at the
* end of this routine but since all the later checks are fatal
* we'll just do this here.
* we'll just do this here. If there is a code signature after
* string table don't do this.
*/
if(rounded_strend != strend)
if(rounded_strend != strend && object->code_sig_cmd == NULL)
object->object_size = strend;
end = object->st->stroff;
}

View File

@ -27,24 +27,18 @@ static void (*dispose)(LLVMDisasmContextRef) = NULL;
static size_t (*disasm)(LLVMDisasmContextRef, uint8_t *, uint64_t, uint64_t,
char *, size_t) = NULL;
static int (*options)(LLVMDisasmContextRef, uint64_t) = NULL;
static const char * (*version)(void) = NULL;
/*
* Wrapper to dynamically load LIB_LLVM and call LLVMCreateDisasm().
* load_llvm() will dynamically load libLTO.dylib if tried_to_load_llvm is 0,
* and set llvm_handle to the value returned by dlopen() and set the function
* pointers.
*/
__private_extern__
LLVMDisasmContextRef
llvm_create_disasm(
const char *TripleName,
const char *CPU,
void *DisInfo,
int TagType,
LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp)
static void load_llvm(void)
{
uint32_t bufsize;
char *p, *prefix, *llvm_path, buf[MAXPATHLEN], resolved_name[PATH_MAX];
int i;
LLVMDisasmContextRef DC;
if(tried_to_load_llvm == 0){
tried_to_load_llvm = 1;
@ -75,7 +69,7 @@ LLVMSymbolLookupCallback SymbolLookUp)
llvm_handle = dlopen("/usr/lib/llvm/" LIB_LLVM, RTLD_NOW);
}
if(llvm_handle == NULL)
return(0);
return;
create = dlsym(llvm_handle, "LLVMCreateDisasm");
dispose = dlsym(llvm_handle, "LLVMDisasmDispose");
@ -84,6 +78,7 @@ LLVMSymbolLookupCallback SymbolLookUp)
/* Note we allow these to not be defined */
options = dlsym(llvm_handle, "LLVMSetDisasmOptions");
createCPU = dlsym(llvm_handle, "LLVMCreateDisasmCPU");
version = dlsym(llvm_handle, "lto_get_version");
if(create == NULL ||
dispose == NULL ||
@ -98,9 +93,32 @@ LLVMSymbolLookupCallback SymbolLookUp)
dispose = NULL;
disasm = NULL;
options = NULL;
return(NULL);
version = NULL;
return;
}
}
if(llvm_handle == NULL)
return;
}
/*
* Wrapper to dynamically load LIB_LLVM and call LLVMCreateDisasm().
*/
__private_extern__
LLVMDisasmContextRef
llvm_create_disasm(
const char *TripleName,
const char *CPU,
void *DisInfo,
int TagType,
LLVMOpInfoCallback GetOpInfo,
LLVMSymbolLookupCallback SymbolLookUp)
{
LLVMDisasmContextRef DC;
if(tried_to_load_llvm == 0){
load_llvm();
}
if(llvm_handle == NULL)
return(NULL);
@ -165,3 +183,20 @@ uint64_t Options)
return(0);
return(options(DC, Options));
}
/*
* Wrapper to call lto_get_version().
*/
__private_extern__
const char *
llvm_disasm_version_string(void)
{
if(tried_to_load_llvm == 0){
load_llvm();
}
if(llvm_handle == NULL)
return(NULL);
if(version == NULL)
return(NULL);
return(version());
}

View File

@ -2925,9 +2925,17 @@ struct ofile *ofile)
if(is_llvm_bitcode(ofile, ofile->file_addr +
ofile->member_offset + ofile->fat_archs[i].offset,
ofile->fat_archs[i].size) == TRUE){
ofile->member_type = OFILE_LLVM_BITCODE;
ofile->object_addr = ofile->member_addr;
ofile->object_size = ofile->member_size;
#ifdef ALIGNMENT_CHECKS_ARCHIVE_64_BIT
if(archive_64_bit_align_warning == FALSE &&
(ofile->member_offset + ofile->fat_archs[i].offset) %
8 != 0){
temporary_archive_member_warning(ofile, "fat object "
"file's offset in archive not a multiple of 8) "
"(must be since member is a 64-bit object file)");
archive_64_bit_align_warning = TRUE;
/* return(CHECK_BAD); */
}
#endif
}
else
#endif /* LTO_SUPPORT */

View File

@ -1,4 +1,4 @@
.TH AS 1 "March 30, 2012" "Apple, Inc."
.TH AS 1 "March 20, 2014" "Apple Inc."
.SH NAME
as \- Mac OS X Mach-O GNU-based assemblers
.SH SYNOPSIS
@ -172,7 +172,7 @@ such temporary labels.
.B \-q
Use the
.IR clang (1)
intergrated assembler instead of the GNU based system assembler. This is
integrated assembler instead of the GNU based system assembler. This is
available for the x86 and arm architectures.
.B \-Q
Used the GNU based system assembler.

View File

@ -1,4 +1,4 @@
.TH LIBTOOL 1 "September 24, 2008" "Apple Inc."
.TH LIBTOOL 1 "January 27, 2014" "Apple Inc."
.SH NAME
libtool \- create libraries
.br
@ -16,6 +16,9 @@ ranlib \- add or update the table of contents of archive libraries
[
.BI -arch_only " arch_type"
]
[
.B \-no_warning_for_no_symbols
]
.IR file ...
[-filelist listfile[,dirname]]
.br
@ -422,6 +425,9 @@ and
.B \-
Treat all remaining arguments as names of files (or archives) and not as
options.
.TP
.B \-no_warning_for_no_symbols
Don't warn about file that have no symbols.
.SH "SEE ALSO"
ld(1), ar(1), otool(1), make(1), redo_prebinding(1), ar(5)
.SH BUGS

View File

@ -1,4 +1,4 @@
.TH OTOOL 1 "November 21, 2013" "Apple, Inc."
.TH OTOOL 1 "January 24, 2014" "Apple Inc."
.SH NAME
otool \- object file displaying tool
.SH SYNOPSIS
@ -11,9 +11,9 @@ otool \- object file displaying tool
.SH DESCRIPTION
The
.I otool
command displays specified parts of object files or libraries. If the,
command displays specified parts of object files or libraries. If the
.B \-m
option is not used, the file
option is not used the file
arguments may be of the form
.IR "libx.a(foo.o)" ,
to request information about only that object file and not
@ -51,10 +51,12 @@ Display the load commands.
.TP
.B \-L
Display the names and version numbers of the shared libraries that the object
file uses. As well as the shared library ID if the file is a shared library.
file uses, as well as the shared library ID if the file is a shared library.
.TP
.B \-D
Display just install name of a shared library.
Display just the install name of a shared library. See
.IR install_name_tool (1)
for more info.
.TP
.BI \-s " segname sectname"
Display the contents of the section
@ -72,9 +74,9 @@ flag is specified.
.B \-t
Display the contents of the (\_\^\_TEXT,\_\^\_text) section. With the
.B \-v
flag, this disassembles the text. And with
.BR \-V ,
it also symbolically disassembles the operands.
flag, this disassembles the text. With the
.B \-V
flag, it also symbolically disassembles the operands.
.TP
.B \-d
Display the contents of the (\_\^\_DATA,\_\^\_data) section.
@ -138,7 +140,7 @@ option.
Don't print leading addresses or headers with disassembly of sections.
.TP
.B \-q
Use the llvm disassembler when doing disassembly, this is available for the x86
Use the llvm disassembler when doing disassembly; this is available for the x86
and arm architectures. This is the default.
.TP
.BI \-mcpu= arg
@ -148,9 +150,9 @@ When doing disassembly using the llvm disassembler use the cpu
.B \-function_offsets
When doing disassembly print the decimal offset from the last label printed.
.TP
.TP
.B \-j
When doing disassembly print the print the opcode bytes of the instructions.
.TP
.B \-Q
Use
.IR otool (1)'s
@ -161,9 +163,10 @@ Specifies the architecture,
.I arch_type,
of the file for
.IR otool (1)
to operate on when the file is a universal file. (See
to operate on when the file is a universal file (aka a file with multiple
architectures). (See
.IR arch (3)
for the currently know
for the currently known
.IR arch_type s.)
The
.I arch_type
@ -174,5 +177,10 @@ otherwise, all architectures in the file are shown.
.B \-m
The object file names are not assumed to be in the archive(member) syntax,
which allows file names containing parenthesis.
.TP
.B \-\-version
Print the
.IR otool (1)
version information.
.SH "SEE ALSO"
install_name_tool(1), dyld(1) and libtool(1)

View File

@ -149,6 +149,8 @@ struct cmd_flags {
enum bool noflush; /* don't use the output_flush routine to flush the
static library output file by pages */
uint32_t debug; /* debug value to debug output_flush() routine */
enum bool /* don't warn if members have no symbols */
no_warning_for_no_symbols;
};
static struct cmd_flags cmd_flags = { 0 };
@ -975,6 +977,9 @@ char **envp)
else if(strcmp(argv[i], "-noflush") == 0){
cmd_flags.noflush = TRUE;
}
else if(strcmp(argv[i], "-no_warning_for_no_symbols") == 0){
cmd_flags.no_warning_for_no_symbols = TRUE;
}
#ifdef DEBUG
else if(strcmp(argv[i], "-debug") == 0){
if(i + 1 >= argc){
@ -1264,7 +1269,7 @@ void)
else{
fprintf(stderr, "Usage: %s -static [-] file [...] "
"[-filelist listfile[,dirname]] [-arch_only arch] "
"[-sacLT]\n", progname);
"[-sacLT] [-no_warning_for_no_symbols]\n", progname);
fprintf(stderr, "Usage: %s -dynamic [-] file [...] "
"[-filelist listfile[,dirname]] [-arch_only arch] "
"[-o output] [-install_name name] "
@ -1720,8 +1725,16 @@ struct ofile *ofile)
if(ofile->mh != NULL || ofile->mh64 != NULL)
size = rnd(ofile->object_size, 8);
#ifdef LTO_SUPPORT
else if(ofile->lto != NULL && ofile->file_type == OFILE_LLVM_BITCODE)
size = rnd(ofile->file_size, 8);
else if(ofile->lto != NULL){
if(ofile->file_type == OFILE_LLVM_BITCODE)
size = rnd(ofile->file_size, 8);
else if(ofile->file_type == OFILE_FAT ||
(ofile->file_type == OFILE_ARCHIVE &&
ofile->member_type == OFILE_FAT))
size = rnd(ofile->object_size, 8);
else
size = rnd(ofile->member_size, 8);
}
#endif /* LTO_SUPPORT */
else
size = rnd(ofile->member_size, 8);
@ -2160,6 +2173,16 @@ struct ofile *ofile)
member->lto = ofile->lto;
member->object_byte_sex = get_byte_sex_from_flag(&arch->arch_flag);
}
else if((ofile->file_type == OFILE_FAT &&
ofile->arch_type == OFILE_LLVM_BITCODE) ||
(ofile->file_type == OFILE_ARCHIVE &&
ofile->member_type == OFILE_FAT &&
ofile->arch_type == OFILE_LLVM_BITCODE)){
member->object_addr = ofile->object_addr;
member->object_size = ofile->object_size;
member->lto = ofile->lto;
member->object_byte_sex = get_byte_sex_from_flag(&arch->arch_flag);
}
#endif /* LTO_SUPPORT */
else{
member->object_addr = ofile->member_addr;
@ -3553,8 +3576,10 @@ char *output)
}
}
}
else
warn_member(arch, member, "has no symbols");
else{
if(cmd_flags.no_warning_for_no_symbols == FALSE)
warn_member(arch, member, "has no symbols");
}
}
#ifdef LTO_SUPPORT
else if(member->lto != NULL){

View File

@ -147,6 +147,10 @@ static struct fat_arch *arm64_fat_arch = NULL;
static struct fat_arch *get_arm64_fat_arch(
void);
static struct fat_arch *x86_64h_fat_arch = NULL;
static struct fat_arch *get_x86_64h_fat_arch(
void);
static enum bool verify_flag = FALSE;
static struct arch_flag *verify_archs = NULL;
static uint32_t nverify_archs = 0;
@ -875,6 +879,9 @@ create_fat(void)
/* We will order the ARM64 slice last. */
arm64_fat_arch = get_arm64_fat_arch();
/* We will order the x86_64h slice last too. */
x86_64h_fat_arch = get_x86_64h_fat_arch();
/* Fill in the fat header and the fat_arch's offsets. */
fat_header.magic = FAT_MAGIC;
fat_header.nfat_arch = nthin_files;
@ -913,6 +920,12 @@ create_fat(void)
*/
if(arm64_fat_arch == &(thin_files[i].fat_arch))
continue;
/*
* If we are ordering the x86_64h slice last too of the fat_arch
* structs, so skip it in this loop.
*/
if(x86_64h_fat_arch == &(thin_files[i].fat_arch))
continue;
#ifdef __LITTLE_ENDIAN__
swap_fat_arch(&(thin_files[i].fat_arch), 1,BIG_ENDIAN_BYTE_SEX);
#endif /* __LITTLE_ENDIAN__ */
@ -940,6 +953,22 @@ create_fat(void)
rename_file);
#ifdef __LITTLE_ENDIAN__
swap_fat_arch(arm64_fat_arch, 1, LITTLE_ENDIAN_BYTE_SEX);
#endif /* __LITTLE_ENDIAN__ */
}
/*
* We are ordering the x86_64h slice so it gets written last too of the
* fat_arch structs, so write it out here as it was skipped above.
*/
if(x86_64h_fat_arch){
#ifdef __LITTLE_ENDIAN__
swap_fat_arch(x86_64h_fat_arch, 1, BIG_ENDIAN_BYTE_SEX);
#endif /* __LITTLE_ENDIAN__ */
if(write(fd, x86_64h_fat_arch,
sizeof(struct fat_arch)) != sizeof(struct fat_arch))
system_fatal("can't write fat arch to output file: %s",
rename_file);
#ifdef __LITTLE_ENDIAN__
swap_fat_arch(x86_64h_fat_arch, 1, LITTLE_ENDIAN_BYTE_SEX);
#endif /* __LITTLE_ENDIAN__ */
}
for(i = 0; i < nthin_files; i++){
@ -1571,6 +1600,34 @@ void)
return(NULL);
}
/*
* get_x86_64h_fat_arch() will return a pointer to the fat_arch struct for the
* x86_64h slice in the thin_files[i] if it is present. Else it returns
* NULL.
*/
static
struct fat_arch *
get_x86_64h_fat_arch(
void)
{
uint32_t i;
struct fat_arch *x86_64h_fat_arch;
/*
* Look for a x86_64h slice.
*/
x86_64h_fat_arch = NULL;
for(i = 0; i < nthin_files; i++){
if(thin_files[i].fat_arch.cputype == CPU_TYPE_X86_64 &&
(thin_files[i].fat_arch.cpusubtype & ~CPU_SUBTYPE_MASK) ==
CPU_SUBTYPE_X86_64_H){
x86_64h_fat_arch = &(thin_files[i].fat_arch);
return(x86_64h_fat_arch);
}
}
return(NULL);
}
/*
* get_align is passed a pointer to a mach header and size of the object. It
* returns the segment alignment the object was created with. It guesses but

View File

@ -1106,8 +1106,6 @@ struct process_flags *process_flags)
symbol->nl.n_value == 0) ||
symbol->nl.n_type == (N_PBUD | N_EXT))
return(FALSE);
else
return(TRUE);
}
if(cmd_flags->g == TRUE && (symbol->nl.n_type & N_EXT) == 0)
return(FALSE);
@ -1366,6 +1364,11 @@ char *arch_name)
(symbols[i].nl.n_desc & N_SYMBOL_RESOLVER) == N_SYMBOL_RESOLVER)
printf("[symbol resolver] ");
if(ofile->mh_filetype == MH_OBJECT &&
((symbols[i].nl.n_type & N_TYPE) != N_UNDF) &&
(symbols[i].nl.n_desc & N_ALT_ENTRY) == N_ALT_ENTRY)
printf("[alt entry] ");
if((symbols[i].nl.n_desc & N_ARM_THUMB_DEF) == N_ARM_THUMB_DEF)
printf("[Thumb] ");

View File

@ -1078,20 +1078,23 @@ struct object *object)
for(j = 0; j < sg->nsects; j++){
/*
* For section types with indirect tables we
* do not zero out the section size in a stub
* library. As the section size is needed to
* know now many indirect table entries the
* section has. This is a bit odd but programs
* dealing with MH_DYLIB_STUB filetypes special
* case this.
* change the type to S_REGULAR and clear the
* reserved1 and reserved2 fields so not to
* confuse tools that would be trying to look
* at the indirect table since it is now removed
* when creating a stub library.
*/
section_type = s[j].flags & SECTION_TYPE;
if(section_type != S_SYMBOL_STUBS &&
section_type != S_LAZY_SYMBOL_POINTERS &&
section_type != S_LAZY_DYLIB_SYMBOL_POINTERS &&
section_type != S_NON_LAZY_SYMBOL_POINTERS){
s[j].size = 0;
if(section_type == S_SYMBOL_STUBS ||
section_type == S_LAZY_SYMBOL_POINTERS ||
section_type ==
S_LAZY_DYLIB_SYMBOL_POINTERS ||
section_type == S_NON_LAZY_SYMBOL_POINTERS){
s[j].flags = S_REGULAR;
s[j].reserved1 = 0;
s[j].reserved2 = 0;
}
s[j].size = 0;
s[j].addr = 0;
s[j].offset = 0;
s[j].reloff = 0;
@ -1114,20 +1117,23 @@ struct object *object)
for(j = 0; j < sg64->nsects; j++){
/*
* For section types with indirect tables we
* do not zero out the section size in a stub
* library. As the section size is needed to
* know now many indirect table entries the
* section has. This is a bit odd but programs
* dealing with MH_DYLIB_STUB filetypes special
* case this.
* change the type to S_REGULAR and clear the
* reserved1 and reserved2 fields so not to
* confuse tools that would be trying to look
* at the indirect table since it is now removed
* when creating a stub library.
*/
section_type = s64[j].flags & SECTION_TYPE;
if(section_type != S_SYMBOL_STUBS &&
section_type != S_LAZY_SYMBOL_POINTERS &&
section_type != S_LAZY_DYLIB_SYMBOL_POINTERS &&
section_type != S_NON_LAZY_SYMBOL_POINTERS){
s64[j].size = 0;
if(section_type == S_SYMBOL_STUBS ||
section_type == S_LAZY_SYMBOL_POINTERS ||
section_type ==
S_LAZY_DYLIB_SYMBOL_POINTERS ||
section_type == S_NON_LAZY_SYMBOL_POINTERS){
s64[j].flags = S_REGULAR;
s64[j].reserved1 = 0;
s64[j].reserved2 = 0;
}
s64[j].size = 0;
s64[j].addr = 0;
s64[j].offset = 0;
s64[j].reloff = 0;
@ -1250,7 +1256,7 @@ struct object *object)
*
* 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
* have been changed to an "ld -r" file and may not be the
* the original input file.
*/
object->output_sym_info_size = 0;
@ -1285,6 +1291,23 @@ struct object *object)
else if (object->dyld_info->rebase_size != 0)
dyld_info_end = object->dyld_info->rebase_off
+ object->dyld_info->rebase_size;
#ifndef NMEDIT
/*
* When stripping out the section contents to create a
* dynamic library stub we only keep the dyld export data.
*/
if(cflag){
if(object->dyld_info->export_off != 0){
dyld_info_start = object->dyld_info->export_off;
dyld_info_end = object->dyld_info->export_off
+ object->dyld_info->export_size;
}
else{
dyld_info_start = 0;
dyld_info_end = 0;
}
}
#endif /* !(NMEDIT) */
object->output_dyld_info = object->object_addr +dyld_info_start;
object->output_dyld_info_size = dyld_info_end - dyld_info_start;
object->output_sym_info_size += object->output_dyld_info_size;
@ -1303,6 +1326,23 @@ struct object *object)
+ object->dyld_info->weak_bind_size
+ object->dyld_info->lazy_bind_size
+ object->dyld_info->export_size;
#ifndef NMEDIT
/*
* When stripping out the section contents to create a
* dynamic library stub we only keep the dyld export data,
* so zero the offsets and sizes of the other dyld data items.
*/
if(cflag){
object->dyld_info->rebase_off = 0;
object->dyld_info->rebase_size = 0;
object->dyld_info->bind_off = 0;
object->dyld_info->bind_size = 0;
object->dyld_info->weak_bind_off = 0;
object->dyld_info->weak_bind_size = 0;
object->dyld_info->lazy_bind_off = 0;
object->dyld_info->lazy_bind_size = 0;
}
#endif /* !(NMEDIT) */
}
if(object->dyst != NULL){
@ -1323,35 +1363,63 @@ struct object *object)
}
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;
#ifndef NMEDIT
/*
* When stripping out the section contents to create a
* dynamic library stub we also remove the split info data.
*/
if(!cflag)
#endif /* !(NMEDIT) */
{
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->output_sym_info_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;
#ifndef NMEDIT
/*
* When stripping out the section contents to create a
* dynamic library stub we also remove the function starts info.
*/
if(!cflag)
#endif /* !(NMEDIT) */
{
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->output_sym_info_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;
#ifndef NMEDIT
/*
* When stripping out the section contents to create a
* dynamic library stub we also remove the data in code info.
*/
if(!cflag)
#endif /* !(NMEDIT) */
{
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->output_sym_info_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){
@ -1418,9 +1486,19 @@ struct object *object)
}
if(object->dyst != NULL){
object->output_sym_info_size +=
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 indirect symbol table also gets
* stripped.
*/
if(!cflag)
#endif /* !(NMEDIT) */
{
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);
@ -1503,10 +1581,23 @@ struct object *object)
object->dyst->iundefsym = new_nlocalsym + new_nextdefsym;
object->dyst->nundefsym = new_nundefsym;
if(object->dyst->nindirectsyms != 0){
object->output_indirect_symtab = indirectsyms;
if(object->object_byte_sex != host_byte_sex)
swap_indirect_symbols(indirectsyms, nindirectsyms,
object->object_byte_sex);
#ifndef NMEDIT
/*
* When stripping out the section contents to create a
* dynamic library stub the indirect symbol table also gets
* stripped.
*/
if(cflag){
object->dyst->nindirectsyms = 0;
}
else
#endif /* !(NMEDIT) */
{
object->output_indirect_symtab = indirectsyms;
if(object->object_byte_sex != host_byte_sex)
swap_indirect_symbols(indirectsyms, nindirectsyms,
object->object_byte_sex);
}
}
/*
@ -1604,18 +1695,60 @@ struct object *object)
object->dyst->locreloff = 0;
if(object->split_info_cmd != NULL){
object->split_info_cmd->dataoff = offset;
offset += object->split_info_cmd->datasize;
#ifndef NMEDIT
/*
* When stripping out the section contents to create a
* dynamic library stub the split info data gets
* stripped.
*/
if(cflag){
object->split_info_cmd->dataoff = 0;
object->split_info_cmd->datasize = 0;
}
else
#endif /* defined(NMEDIT) */
{
object->split_info_cmd->dataoff = offset;
offset += object->split_info_cmd->datasize;
}
}
if(object->func_starts_info_cmd != NULL){
object->func_starts_info_cmd->dataoff = offset;
offset += object->func_starts_info_cmd->datasize;
#ifndef NMEDIT
/*
* When stripping out the section contents to create a
* dynamic library stub the function starts info gets
* stripped.
*/
if(cflag){
object->func_starts_info_cmd->dataoff = 0;
object->func_starts_info_cmd->datasize = 0;
}
else
#endif /* defined(NMEDIT) */
{
object->func_starts_info_cmd->dataoff = offset;
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;
#ifndef NMEDIT
/*
* When stripping out the section contents to create a
* dynamic library stub the data in code info gets
* stripped.
*/
if(cflag){
object->data_in_code_cmd->dataoff = 0;
object->data_in_code_cmd->datasize = 0;
}
else
#endif /* defined(NMEDIT) */
{
object->data_in_code_cmd->dataoff = offset;
offset += object->data_in_code_cmd->datasize;
}
}
if(object->code_sign_drs_cmd != NULL){
@ -1675,9 +1808,23 @@ struct object *object)
object->dyst->extreloff = 0;
if(object->dyst->nindirectsyms != 0){
object->dyst->indirectsymoff = offset;
offset += 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 indirect symbol table also gets
* stripped.
*/
if(cflag){
object->dyst->indirectsymoff = 0;
}
else
#endif /* defined(NMEDIT) */
{
object->dyst->indirectsymoff = offset;
offset += object->dyst->nindirectsyms *
sizeof(uint32_t) +
object->input_indirectsym_pad;
}
}
else
object->dyst->indirectsymoff = 0;;

View File

@ -838,6 +838,8 @@ const char **ReferenceName)
*ReferenceType =
LLVMDisassembler_ReferenceType_DeMangled_Name;
}
else
*ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
}
else
*ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;

View File

@ -5276,6 +5276,8 @@ const char **ReferenceName)
*ReferenceType =
LLVMDisassembler_ReferenceType_DeMangled_Name;
}
else
*ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
}
else
*ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;

View File

@ -320,8 +320,9 @@ char **envp)
uint32_t j, nfiles;
struct arch_flag *arch_flags;
uint32_t narch_flags;
enum bool all_archs, use_member_syntax;
enum bool all_archs, use_member_syntax, version;
char **files;
const char *disssembler_version;
progname = argv[0];
arch_flags = NULL;
@ -329,6 +330,7 @@ char **envp)
all_archs = TRUE;
use_member_syntax = TRUE;
llvm_mc = FALSE;
version = FALSE;
if(argc <= 1)
usage();
@ -348,6 +350,15 @@ char **envp)
files[nfiles++] = argv[i];
continue;
}
if(strcmp(argv[i], "--version") == 0){
fprintf(stderr, "otool(1): Apple Inc. version %s\n",
apple_version);
disssembler_version = llvm_disasm_version_string();
if(disssembler_version != NULL)
fprintf(stderr, "disassmbler: %s\n", disssembler_version);
version = TRUE;
continue;
}
if(strcmp(argv[i], "-arch") == 0){
if(i + 1 == argc){
error("missing argument(s) to %s option", argv[i]);
@ -550,9 +561,10 @@ char **envp)
*/
if(!fflag && !aflag && !hflag && !lflag && !Lflag && !tflag && !dflag &&
!oflag && !Oflag && !rflag && !Tflag && !Mflag && !Rflag && !Iflag &&
!Cflag && !print_bind_info &&
!Cflag && !print_bind_info && !version &&
!Hflag && !Gflag && !Sflag && !cflag && !iflag && !Dflag &&!segname){
error("one of -fahlLtdoOrTMRIHCGScis must be specified");
error("one of -fahlLtdoOrTMRIHCGScis or --version must be "
"specified");
usage();
}
if(qflag && Qflag){
@ -565,7 +577,7 @@ char **envp)
*/
if(!Qflag)
qflag = TRUE;
if(nfiles == 0){
if(nfiles == 0 && version == FALSE){
error("at least one file must be specified");
usage();
}
@ -607,7 +619,7 @@ void)
{
fprintf(stderr,
"Usage: %s [-arch arch_type] [-fahlLDtdorSTMRIHGvVcXmqQjC] "
"[-mcpu=arg] <object file> ...\n", progname);
"[-mcpu=arg] [--version] <object file> ...\n", progname);
fprintf(stderr, "\t-f print the fat headers\n");
fprintf(stderr, "\t-a print the archive header\n");
@ -644,6 +656,7 @@ void)
fprintf(stderr, "\t-mcpu=arg use `arg' as the cpu for disassembly\n");
fprintf(stderr, "\t-j print opcode bytes\n");
fprintf(stderr, "\t-C print linker optimization hints\n");
fprintf(stderr, "\t--version print the version of %s\n", progname);
exit(EXIT_FAILURE);
}
@ -3180,6 +3193,8 @@ uint64_t seg_addr)
}
llvm_disasm_set_options(i386_dc,
LLVMDisassembler_Option_PrintImmHex);
llvm_disasm_set_options(i386_dc,
LLVMDisassembler_Option_SetInstrComments);
if(eflag)
llvm_disasm_set_options(i386_dc,
LLVMDisassembler_Option_UseMarkup);
@ -3192,6 +3207,8 @@ uint64_t seg_addr)
}
llvm_disasm_set_options(x86_64_dc,
LLVMDisassembler_Option_PrintImmHex);
llvm_disasm_set_options(x86_64_dc,
LLVMDisassembler_Option_SetInstrComments);
if(eflag)
llvm_disasm_set_options(x86_64_dc,
LLVMDisassembler_Option_UseMarkup);

View File

@ -1812,6 +1812,10 @@ NS32:
printf(" MH_NO_HEAP_EXECUTION");
f &= ~MH_NO_HEAP_EXECUTION;
}
if(f & MH_APP_EXTENSION_SAFE){
printf(" APP_EXTENSION_SAFE");
f &= ~MH_APP_EXTENSION_SAFE;
}
if(f != 0 || flags == 0)
printf(" 0x%08x", (unsigned int)f);
printf("\n");

View File

@ -622,8 +622,15 @@ struct info *info)
printf(" %s\n", name);
else
printf("\n");
printf(" data 0x%x (struct class_ro_t *)\n", c.data);
print_class_ro_t(c.data, info, &is_meta_class);
printf(" data 0x%x (struct class_ro_t *)", c.data);
/*
* This is a Swift class if some of the low bits of the pointer
* are set.
*/
if(c.data & 0x3)
printf(" Swift class");
printf("\n");
print_class_ro_t(c.data & ~0x3, info, &is_meta_class);
if(! is_meta_class)
{

View File

@ -808,8 +808,14 @@ struct info *info)
printf("0x%llx", c.data);
}
printf(" (struct class_ro_t *)");
/*
* This is a Swift class if some of the low bits of the pointer
* are set.
*/
if((c.data + n_value) & 0x7)
printf(" Swift class");
printf("\n");
print_class_ro_t(c.data + n_value, info, &is_meta_class);
print_class_ro_t((c.data + n_value) & ~0x7, info, &is_meta_class);
if(is_meta_class == FALSE){
printf("Meta Class\n");
@ -1776,6 +1782,8 @@ enum bool verbose)
object_addr, object_size, &info.sections,
&info.nsections, &info.database);
o = get_section_64(info.sections, info.nsections, SEG_OBJC, sectname);
if(o == NULL)
return;
get_cstring_section_64(load_commands, ncmds, sizeofcmds,object_byte_sex,
object_addr, object_size, &cstring_section);