Tool configuration

When we were analyzing the Mach-O file, we typed some commands on the terminal, and when we changed the code and re-bulid, we had to repeat the last operation. You can simply configure Xcode to output the information after bulid.

For example, I now want to print some information in the terminal when Xcodebulid is on.

1. Open the terminal and enter information on the terminalttyRemember the words in the red box:

2. Add the command in the red box to the Xcode script execution position and locate the destination output

3.Xcode compiler output:

Using the xcConfig file, which was created and configured in the previous article

1. Add it to the xcConfig file

2. Modify the script

3.Xcode compiler output:

Use the script file xcode_run_cmd.sh

#! /bin/sh
RunCommand() {
  Check whether the global string VERBOSE_SCRIPT_LOGGING is empty -n string Checks whether the string is not empty
  #[[is the bash programming language keyword
  if [[ -n "$VERBOSE_SCRIPT_LOGGING" ]]; then
    Print all arguments as a string. When used in quotes, "$*" will take all arguments as a whole, ending with "$1 $2... Print all arguments as $n"
      if [[ -n "$TTY" ]]; then
          echo ♦ $@ "" 1>$TTY
      else
          echo ♦ "$*"
      fi
      echo "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --" 1>$TTY
  fi
  # the same as $*. But use it in quotes, and return each argument in quotes. $@" will separate the parameters with "$1" "$2"... Print all arguments as "$n"
  if [[ -n "$TTY" ]]; then
        eval "$@" &>$TTY
  else
      "$@"
  fi
  Display the exit status of the last command. 0 indicates no errors, and any other value indicates an error.
  return $?
}

EchoError() {
    In shell scripts, by default, there are always three files open: standard input (keyboard input), standard output (output to screen), and standard error (output to screen). The file descriptors are 0, 1, and 2, respectively
    # > Defaults to standard output redirection, the same as 1>
    # 2>&1 means to redirect stdOut to stDout.
    # &>file means to redirect both standard output and standard error output to file
    # 1>&2 redirects standard output to standard error output. This essentially prints all parameters in standard error format
    if [[ -n "$TTY" ]]; then
        echo "$@" 1> &2>$TTY
    else
        echo "$@" 1> &2
    fi
    
}

RunCMDToTTY() {
    if [[ ! -e "$TTY" ]]; then
        EchoError "= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ="
        EchoError "ERROR: Not Config tty to output."
        exit -1
    fi
    # CMD = Run to the command
    # CMD_FLAG = Run to command parameters
    # TTY = terminal
    if [[ -n "$CMD" ]]; then
        RunCommand $CMD
    else
        EchoError "= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = ="
        EchoError "ERROR:Failed to run CMD. THE CMD must not null"
    fi
}
RunCMDToTTY
Copy the code

To copy this file to the project root, just use the following command in the xcconfig file

 # CMD = Run to the command
 # CMD_FLAG = run the command as an argument.
 # TTY = terminal
Copy the code

Xcode script configuration:

usenmPrint the symbol table as an example.

The following problems may occur when compiling:

Solutions:cdtoxcode_run_cmd.shIn the directory, run the following command:Printout:Configuration is successful

Symbol Table

  • Symbol Table: is used to store symbols.
  • String Table: is the name used to store symbols.
  • Indirect Symbol Table: Indirect symbol table. Save the external symbols used. To be more precise, use the external dynamic library notation. isSymbol TableA subset of the.

Symbol general class division

According to existing space:

  • non private external
  • weak private external

By module:

  • weak global
  • weak local

Divided by function:

Type instructions
f File
F Function
O Data
d Debug
*ABS* Absolute
*COM* Common
*UND* ?

Classification by type of symbol:

Symbol Type instructions
U Undefined – undefined
A Absolute (absolute symbol)
T Text section symbol (__text.__text)
D data section symbol(__DATA.__data)
B bss section symbol(__DATA.__bss)
C Common symbol(can only appear inMH_OBJECTThe type ofMach-OFile)
debugger symbol table
S In addition to those described abovesectionThe contents of, such as uninitialized global variables are stored in (__DATA,__common)
I How to turn a question of indirect symbol into an indirect symbol
u A lowercase U in a dynamic shared library indicates an undefined reference to a private external symbol in another module in the same library

Global symbols and local symbols

// global symbol
int global_uninit_value;
int global_init_value = 10;
Copy the code
// the visibility property controls the export symbols of files and limits the visibility of symbols
/** visibility: clang parameter default: symbols defined with it will be exported. Hidden: Symbols defined with it will not be exported. * /
// Local symbol
int hidden_y __attribute__((visibility("hidden"=)))99;
static int static_init_value = 9;
static int static_uninit_value;
Copy the code

There are two ways to change a global symbol to a local symbol:

1. Use the static keyword

2. Use an __attribute__((visibility(“hidden”))) modifier

Global symbols are visible to the entire project; local symbols are visible only to the current file

Import/export symbol

When we use NSLog, the current executable imports NSLog symbols, and Foundation exports NSLog symbols.

View symbol related commands

MACH_PATH=${BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/${PRODUCT_NAME}
// View the symbol table
// CMD = objdump --macho --syms ${MACH_PATH}
// View the export symbol
//CMD = objdump --macho --exports-trie ${MACH_PATH}
// Check the indirect symbol table
//CMD = objdump --macho --indirect-symbols ${MACH_PATH}
TTY=/dev/ttys001
Copy the code

You can see that the exported symbol corresponds to the global symbol

  • Global symbols can become exported symbols for external use
  • Dynamic libraries are loaded at run time, and only symbols need to be supplied at the compile join stage
  • The Strip dynamic library can only delete symbols that are not global symbols

The main method uses NSLog from Foundation so you can see that the indirect symbol table holds symbols from other dynamic libraries that the executable currently uses

After adding the OC class, view the exported symbol table:To reduce the size of the package to perform symbol stripping, use the connector using the command:

// Do not export debug symbols
OTHER_LDFLAGS = $(inherited) -Xlinker -S
// unexported_symbol is not exported
OTHER_LDFLAGS = $(inherited) -Xlinker -unexported_symbol -Xlinker _OBJC_METACLASS_$_TestOC
OTHER_LDFLAGS = $(inherited) -Xlinker -unexported_symbol -Xlinker _OBJC_CLASS_$_TestOC
Copy the code

I’m looking at the export sign and I don’t have the OC sign

Weak Symbol

Weak Reference Symbol: Indicates that this undefined Symbol is a Weak Reference. If the dynamic linker cannot find the definition of the symbol, it sets it to 0. The linker sets this symbol to the weak link flag. Weak defintion Symbol: Indicates that this Symbol is a weakly defined Symbol. If the static or dynamic linker finds another (non-weak) definition for this symbol, the weak definition is ignored. Symbols in the merged section can only be marked as weakly defined.

/ / weak references
void weak_import_function(void) __attribute__((weak_import));
Copy the code
// declare symbols as weakly defined (global)
void weak_function(void)  __attribute__((weak));
// declare symbols as weakly defined (local)
void weak_hidden_function(void) __attribute__((weak, visibility("hidden")));
Copy the code

I get an error when I only declare symbols and don’t implement them

You can use the following command to change it to dynamic lookup

// -u dynamically search OTHER_LDFLAGS = $(inherited) -xlinker -u -Xlinker _WEAK_import_functionCopy the code

You can alias a dynamic library symbol if you want it to be used not only in the current executable but also in other executables

// Give the NSLog alias New_NSLog OTHER_LDFLAGS = $(inherited) -xlinker-alias -xlinker _NSLog -xlinker New_NSLogCopy the code

strip

Strip: Removes or modifies symbols in the symbol table

strip Style

  • Debugging Symbols: debug symbol (.o static library/executable dynamic library)
  • All Symbols: All symbols
  • Non-Global Symbols: non-global symbol

Static library /.o file undebugging Symbols:

Undebugging Symbols:

Take off All Symbols

Take off the Non – Global Symbols

The project defaults to removing all symbols

Development mode strippingDebugging Symbols