Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / native_client / pnacl / driver / pnacl-ld.py
index 55eeafc..9baea5b 100755 (executable)
@@ -2,18 +2,15 @@
 # Copyright (c) 2012 The Native Client Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
-#
-# IMPORTANT NOTE: If you make local mods to this file, you must run:
-#   %  pnacl/build.sh driver
-# in order for them to take effect in the scons build.  This command
-# updates the copy in the toolchain/ tree.
-#
-
-from driver_tools import *
+
+from driver_tools import ArchMerge, DriverChain, GetArch, \
+    ParseArgs, ParseTriple, RunDriver, RunWithEnv, SetArch, \
+    SetExecutableMode, TempNameGen, UnrecognizedOption
 from driver_env import env
-from driver_log import Log, DriverOpen, TempFiles
+from driver_log import Log
 import filetype
-import platform
+import ldtools
+import pathtools
 
 EXTRA_ENV = {
   'ALLOW_NATIVE': '0', # Allow LD args which will change the behavior
@@ -24,7 +21,6 @@ EXTRA_ENV = {
   'INPUTS'   : '',
   'OUTPUT'   : '',
 
-  'SHARED'   : '0',
   'STATIC'   : '0',
   'PIC'      : '0',
   'USE_STDLIB': '1',
@@ -42,18 +38,14 @@ EXTRA_ENV = {
                     # requested or not, since we don't want to propagate
                     # the value to TRANSLATE_FLAGS if it wasn't explicitly set.
   'OPT_LTO_FLAGS': '-std-link-opts -disable-internalize',
-  'OPT_FLAGS': '${#OPT_LEVEL && !OPT_LEVEL == 0 ? ${OPT_LTO_FLAGS}} ${OPT_STRIP_%STRIP_MODE%} ' +
+  'OPT_FLAGS': '${#OPT_LEVEL && !OPT_LEVEL == 0 ? ${OPT_LTO_FLAGS}} ' +
                '-inline-threshold=${OPT_INLINE_THRESHOLD} ',
-  'OPT_STRIP_none': '',
-  'OPT_STRIP_all': '-disable-opt --strip',
-  'OPT_STRIP_debug': '-disable-opt --strip-debug',
 
   'TRANSLATE_FLAGS': '${PIC ? -fPIC} ${!USE_STDLIB ? -nostdlib} ' +
-                     '${STATIC ? -static} ' +
-                     '${SHARED ? -shared} ' +
                      '${#SONAME ? -Wl,--soname=${SONAME}} ' +
                      '${#OPT_LEVEL ? -O${OPT_LEVEL}} ' +
                      '--allow-llvm-bitcode-input ' +
+                     '${CXX_EH_MODE==zerocost ? --pnacl-allow-zerocost-eh} ' +
                      '${TRANSLATE_FLAGS_USER}',
 
   # Extra pnacl-translate flags specified by the user using -Wt
@@ -63,7 +55,7 @@ EXTRA_ENV = {
                       '-plugin-opt=emit-llvm',
 
   'LD_FLAGS'       : '-nostdlib ${@AddPrefix:-L:SEARCH_DIRS} ' +
-                     '${SHARED ? -shared} ${STATIC ? -static} ' +
+                     '${STATIC ? -static} ' +
                      '${RELOCATABLE ? -relocatable} ' +
                      '${#SONAME ? --soname=${SONAME}}',
 
@@ -76,16 +68,19 @@ EXTRA_ENV = {
 
   # Standard Library Directories
   'SEARCH_DIRS_BUILTIN': '${USE_STDLIB ? ' +
+                         '  ${BASE_USR}/usr/lib/ ' +
                          '  ${BASE_USR}/lib/ ' +
                          '  ${BASE_SDK}/lib/ ' +
                          '  ${BASE_LIB}/ ' +
                          '}',
 
-  'BCLD_OFORMAT'        : '${BCLD_OFORMAT_%ARCH%}',
-  'BCLD_OFORMAT_ARM'    : 'elf32-littlearm',
-  'BCLD_OFORMAT_X8632'  : 'elf32-i386-nacl',
-  'BCLD_OFORMAT_X8664'  : 'elf64-x86-64-nacl',
-  'BCLD_OFORMAT_MIPS32' : 'elf32-tradlittlemips',
+  'BCLD_OFORMAT'               : '${BCLD_OFORMAT_%ARCH%}',
+  'BCLD_OFORMAT_ARM'           : 'elf32-littlearm',
+  'BCLD_OFORMAT_X8632'         : 'elf32-i386-nacl',
+  'BCLD_OFORMAT_X8664'         : 'elf64-x86-64-nacl',
+  'BCLD_OFORMAT_MIPS32'        : 'elf32-tradlittlemips-nacl',
+  'BCLD_OFORMAT_ARM_NONSFI'    : 'elf32-littlearm',
+  'BCLD_OFORMAT_X8632_NONSFI'  : 'elf32-i386-nacl',
 
   'BCLD_ALLOW_UNRESOLVED'  :
     # The following functions are implemented in the native support library.
@@ -97,8 +92,25 @@ EXTRA_ENV = {
     '--allow-unresolved=memmove '
     '--allow-unresolved=setjmp '
     '--allow-unresolved=longjmp '
+    # These TLS layout functions are either defined by the ExpandTls
+    # pass or (for non-ABI-stable code only) by PNaCl's native support
+    # code.
+    '--allow-unresolved=__nacl_tp_tls_offset '
+    '--allow-unresolved=__nacl_tp_tdb_offset '
+    # __nacl_get_arch() is for non-ABI-stable code only.
+    '--allow-unresolved=__nacl_get_arch '
+    '${CXX_EH_MODE==sjlj ? '
+      # These symbols are defined by libsupc++ and the PNaClSjLjEH
+      # pass generates references to them.
+      '--undefined=__pnacl_eh_stack '
+      '--undefined=__pnacl_eh_resume '
+      # These symbols are defined by the PNaClSjLjEH pass and
+      # libsupc++ refers to them.
+      '--allow-unresolved=__pnacl_eh_type_table '
+      '--allow-unresolved=__pnacl_eh_action_table '
+      '--allow-unresolved=__pnacl_eh_filter_table} '
     # For exception-handling enabled tests.
-    '${ALLOW_CXX_EXCEPTIONS ? '
+    '${CXX_EH_MODE==zerocost ? '
       '--allow-unresolved=_Unwind_Backtrace '
       '--allow-unresolved=_Unwind_DeleteException '
       '--allow-unresolved=_Unwind_GetCFA '
@@ -118,19 +130,16 @@ EXTRA_ENV = {
       '--allow-unresolved=_Unwind_SetIP}',
 
   'BCLD_FLAGS':
-    '--oformat ${BCLD_OFORMAT} -Ttext=0x20000 ' +
-    '${!SHARED && !RELOCATABLE ? --undef-sym-check ${BCLD_ALLOW_UNRESOLVED}} ' +
+    '--oformat ${BCLD_OFORMAT} ' +
+    '${!RELOCATABLE ? --undef-sym-check ${BCLD_ALLOW_UNRESOLVED}} ' +
     '${GOLD_PLUGIN_ARGS} ${LD_FLAGS}',
   'RUN_BCLD': ('${LD} ${BCLD_FLAGS} ${inputs} -o ${output}'),
 
-  'ALLOW_CXX_EXCEPTIONS': '0',
+  'CXX_EH_MODE': 'none',
   'ALLOW_NEXE_BUILD_ID': '0',
   'DISABLE_ABI_CHECK': '0',
   'LLVM_PASSES_TO_DISABLE': '',
-  # Skip dev intrinsic checks in ABI verifier.  Used for pnacl-llc.pexe and
-  # gold.pexe, which currently use llvm.nacl.target.arch.
-  # TODO(jvoung): find way to stop using llvm.nacl.target.arch.
-  'ALLOW_DEV_INTRINSICS': '0',
+  'RUN_PASSES_SEPARATELY': '0',
 }
 
 def AddToBCLinkFlags(*args):
@@ -143,10 +152,6 @@ def AddToBothFlags(*args):
   env.append('LD_FLAGS', *args)
   env.append('LD_FLAGS_NATIVE', *args)
 
-def AddAllowCXXExceptions(*args):
-  env.set('ALLOW_CXX_EXCEPTIONS', '1')
-  env.append('TRANSLATE_FLAGS', *args)
-
 def SetLibTarget(*args):
   arch = ParseTriple(args[0])
   if arch != 'le32':
@@ -158,7 +163,10 @@ def IsPortable():
 LDPatterns = [
   ( '--pnacl-allow-native', "env.set('ALLOW_NATIVE', '1')"),
   ( '--noirt',              "env.set('USE_IRT', '0')"),
-  ( '(--pnacl-allow-exceptions)', AddAllowCXXExceptions),
+  ( '--pnacl-exceptions=(none|sjlj|zerocost)', "env.set('CXX_EH_MODE', $0)"),
+  # TODO(mseaborn): Remove "--pnacl-allow-exceptions", which is
+  # superseded by "--pnacl-exceptions".
+  ( '--pnacl-allow-exceptions', "env.set('CXX_EH_MODE', 'zerocost')"),
   ( '(--pnacl-allow-nexe-build-id)', "env.set('ALLOW_NEXE_BUILD_ID', '1')"),
   ( '--pnacl-disable-abi-check', "env.set('DISABLE_ABI_CHECK', '1')"),
   # "--pnacl-disable-pass" allows an ABI simplification pass to be
@@ -166,18 +174,20 @@ LDPatterns = [
   # required for ABI-stable pexes but can be omitted when the PNaCl
   # toolchain is used for producing native nexes.
   ( '--pnacl-disable-pass=(.+)', "env.append('LLVM_PASSES_TO_DISABLE', $0)"),
-  ( '--pnacl-allow-dev-intrinsics', "env.set('ALLOW_DEV_INTRINSICS', '1')"),
+  ( '--pnacl-run-passes-separately', "env.set('RUN_PASSES_SEPARATELY', '1')"),
   ( ('-target', '(.+)'), SetLibTarget),
   ( ('--target=(.+)'), SetLibTarget),
 
   ( '-o(.+)',          "env.set('OUTPUT', pathtools.normalize($0))"),
   ( ('-o', '(.+)'),    "env.set('OUTPUT', pathtools.normalize($0))"),
+  ( ('--output', '(.+)'), "env.set('OUTPUT', pathtools.normalize($0))"),
 
-  ( '-shared',         "env.set('SHARED', '1')"),
   ( '-static',         "env.set('STATIC', '1')"),
   ( '-nostdlib',       "env.set('USE_STDLIB', '0')"),
+
   ( '-r',              "env.set('RELOCATABLE', '1')"),
   ( '-relocatable',    "env.set('RELOCATABLE', '1')"),
+  ( '-i',              "env.set('RELOCATABLE', '1')"),
 
   ( ('-L', '(.+)'),
     "env.append('SEARCH_DIRS_USER', pathtools.normalize($0))\n"),
@@ -186,20 +196,13 @@ LDPatterns = [
   ( ('--library-path', '(.+)'),
     "env.append('SEARCH_DIRS_USER', pathtools.normalize($0))\n"),
 
-  # We just ignore undefined symbols in shared objects, so
-  # -rpath-link should not be necessary.
-  #
-  # However, libsrpc.so still needs to be linked in directly (in non-IRT mode)
-  # or it malfunctions. This is the only way that -rpath-link is still used.
-  # There's a corresponding hack in pnacl-translate to recognize libsrpc.so
-  # and link it in directly.
-  # TODO(pdox): Investigate this situation.
+  # -rpath and -rpath-link are only relevant to dynamic linking.
+  # Ignore them for compatibility with build scripts that expect to be
+  # able to pass them.
   ( ('(-rpath)','(.*)'), ""),
   ( ('(-rpath)=(.*)'), ""),
-  ( ('(-rpath-link)','(.*)'),
-    "env.append('TRANSLATE_FLAGS', $0+'='+pathtools.normalize($1))"),
-  ( ('(-rpath-link)=(.*)'),
-    "env.append('TRANSLATE_FLAGS', $0+'='+pathtools.normalize($1))"),
+  ( ('(-rpath-link)','(.*)'), ""),
+  ( ('(-rpath-link)=(.*)'), ""),
 
   # This overrides the builtin linker script.
   ( ('(-T)', '(.*)'),    AddToNativeFlags),
@@ -229,7 +232,9 @@ LDPatterns = [
   ( ('-?-soname', '(.*)'),        "env.set('SONAME', $0)"),
 
   ( '(-M)',                       AddToBCLinkFlags),
+  ( '(--print-map)',              AddToBCLinkFlags),
   ( '(-t)',                       AddToBCLinkFlags),
+  ( '(--trace)',                  AddToBCLinkFlags),
   ( ('(-y)','(.*)'),              AddToBCLinkFlags),
   ( ('(-defsym)','(.*)'),         AddToBCLinkFlags),
 
@@ -242,6 +247,9 @@ LDPatterns = [
   ( '-mmipselelf_nacl',      "env.set('ARCH', 'MIPS32')"),
   ( ('-m','mipselelf_nacl'), "env.set('ARCH', 'MIPS32')"),
 
+  ( ('(-?-wrap)', '(.+)'), AddToBCLinkFlags),
+  ( ('(-?-wrap=.+)'),      AddToBCLinkFlags),
+
   # NOTE: For scons tests, the code generation fPIC flag is used with pnacl-ld.
   ( '-fPIC',               "env.set('PIC', '1')"),
 
@@ -265,6 +273,8 @@ LDPatterns = [
   # Inputs and options that need to be kept in order
   ( '(-l.*)',              "env.append('INPUTS', $0)"),
   ( ('(-l)','(.*)'),       "env.append('INPUTS', $0+$1)"),
+  ( ('--library', '(.*)'), "env.append('INPUTS', '-l'+$0)"),
+
   ( '(--no-as-needed)',    "env.append('INPUTS', $0)"),
   ( '(--as-needed)',       "env.append('INPUTS', $0)"),
   ( '(--start-group)',     "env.append('INPUTS', $0)"),
@@ -273,6 +283,8 @@ LDPatterns = [
   ( '(-Bdynamic)',          "env.append('INPUTS', $0)"),
   ( '(--(no-)?whole-archive)', "env.append('INPUTS', $0)"),
   ( '(--undefined=.*)',    "env.append('INPUTS', $0)"),
+  ( ('(-u)','(.*)'),       "env.append('INPUTS', $0+$1)"),
+  ( '(-u.*)',              "env.append('INPUTS', $0)"),
   ( '(-.*)',               UnrecognizedOption),
   ( '(.*)',                "env.append('INPUTS', pathtools.normalize($0))"),
 ]
@@ -306,8 +318,6 @@ def main(argv):
     env.set('BASE_LIB', "${BASE_LIB_ARCH}")
 
   if env.getbool('RELOCATABLE'):
-    if env.getbool('SHARED'):
-      Log.Fatal("-r and -shared may not be used together")
     env.set('STATIC', '0')
 
   inputs = env.get('INPUTS')
@@ -322,6 +332,8 @@ def main(argv):
     SetArch('X8632')
   assert(GetArch() is not None)
 
+  inputs = FixPrivateLibs(inputs)
+
   # Expand all parameters
   # This resolves -lfoo into actual filenames,
   # and expands linker scripts into command-line arguments.
@@ -341,15 +353,7 @@ def main(argv):
 
   regular_inputs, native_objects = SplitLinkLine(inputs)
 
-  if not env.getbool('USE_IRT'):
-    inputs = UsePrivateLibraries(inputs)
-
-  inputs = ReorderPrivateLibs(inputs)
-
-  if env.getbool('SHARED'):
-    bitcode_type = 'pso'
-    native_type = 'so'
-  elif env.getbool('RELOCATABLE'):
+  if env.getbool('RELOCATABLE'):
     bitcode_type = 'po'
     native_type = 'o'
   else:
@@ -382,15 +386,22 @@ def main(argv):
     # not needed.
     abi_simplify = (env.getbool('STATIC') and
                     len(native_objects) == 0 and
-                    not env.getbool('ALLOW_CXX_EXCEPTIONS') and
+                    env.getone('CXX_EH_MODE') != 'zerocost' and
                     not env.getbool('ALLOW_NEXE_BUILD_ID') and
                     IsPortable())
     still_need_expand_byval = IsPortable()
 
-    preopt_passes = []
+    # A list of groups of args. Each group should contain a pass to run
+    # along with relevant flags that go with that pass.
+    opt_args = []
     if abi_simplify:
-      preopt_passes += ['-pnacl-abi-simplify-preopt']
-    elif not env.getbool('ALLOW_CXX_EXCEPTIONS'):
+      pre_simplify = ['-pnacl-abi-simplify-preopt']
+      if env.getone('CXX_EH_MODE') == 'sjlj':
+        pre_simplify += ['-enable-pnacl-sjlj-eh']
+      else:
+        assert env.getone('CXX_EH_MODE') == 'none'
+      opt_args.append(pre_simplify)
+    elif env.getone('CXX_EH_MODE') != 'zerocost':
       # '-lowerinvoke' prevents use of C++ exception handling, which
       # is not yet supported in the PNaCl ABI.  '-simplifycfg' removes
       # landingpad blocks made unreachable by '-lowerinvoke'.
@@ -398,34 +409,35 @@ def main(argv):
       # We run this in order to remove 'resume' instructions,
       # otherwise these are translated to calls to _Unwind_Resume(),
       # which will not be available at native link time.
-      preopt_passes += ['-lowerinvoke', '-simplifycfg']
-    if len(preopt_passes) != 0:
-      chain.add(DoLLVMPasses(preopt_passes), 'simplify_preopt.' + bitcode_type)
+      opt_args.append(['-lowerinvoke', '-simplifycfg'])
 
     if env.getone('OPT_LEVEL') != '' and env.getone('OPT_LEVEL') != '0':
-      chain.add(DoLTO, 'opt.' + bitcode_type)
-    elif env.getone('STRIP_MODE') != 'none':
-      chain.add(DoStrip, 'stripped.' + bitcode_type)
+      opt_args.append(env.get('OPT_FLAGS'))
+    if env.getone('STRIP_MODE') != 'none':
+      opt_args.append(env.get('STRIP_FLAGS'))
 
-    postopt_passes = []
     if abi_simplify:
-      postopt_passes = ['-pnacl-abi-simplify-postopt']
+      post_simplify = ['-pnacl-abi-simplify-postopt']
       if not env.getbool('DISABLE_ABI_CHECK'):
-        postopt_passes += [
+        post_simplify += [
             '-verify-pnaclabi-module',
             '-verify-pnaclabi-functions',
             # A flag for the above -verify-pnaclabi-* passes.
             '-pnaclabi-allow-debug-metadata']
-        if env.getbool('ALLOW_DEV_INTRINSICS'):
-          # A flag for the above -verify-pnaclabi-* passes.
-          postopt_passes += ['-pnaclabi-allow-dev-intrinsics']
+      opt_args.append(post_simplify)
     elif still_need_expand_byval:
       # We may still need -expand-byval to match the PPAPI shim
       # calling convention.
-      postopt_passes = ['-expand-byval']
-    if len(postopt_passes) != 0:
-      chain.add(DoLLVMPasses(postopt_passes),
-                'simplify_postopt.' + bitcode_type)
+      opt_args.append(['-expand-byval'])
+    if len(opt_args) != 0:
+      if env.getbool('RUN_PASSES_SEPARATELY'):
+        for i, group in enumerate(opt_args):
+          chain.add(DoLLVMPasses(group),
+                    'simplify_%d.%s' % (i, bitcode_type))
+      else:
+        flattened_opt_args = [flag for group in opt_args for flag in group]
+        chain.add(DoLLVMPasses(flattened_opt_args),
+                  'simplify_and_opt.' + bitcode_type)
   else:
     chain = DriverChain('', output, tng)
 
@@ -442,49 +454,41 @@ def main(argv):
     SetExecutableMode(output)
   return 0
 
-def UsePrivateLibraries(libs):
-  """ Place libnacl_sys_private.a before libnacl.a
-  Replace libpthread.a with libpthread_private.a
-  Replace libnacl_dyncode.a with libnacl_dyncode_private.a
-  This assumes that the private libs can be found at the same directory
-  as the public libs.
-  """
-  result_libs = []
-  for l in libs:
-    base = pathtools.basename(l)
-    dname = pathtools.dirname(l)
-    if base == 'libnacl.a':
-      Log.Info('Not using IRT -- injecting libnacl_sys_private.a to link line')
-      result_libs.append(pathtools.join(dname, 'libnacl_sys_private.a'))
-      result_libs.append(l)
-    elif base == 'libpthread.a':
-      Log.Info('Not using IRT -- swapping private lib for libpthread')
-      result_libs.append(pathtools.join(dname, 'libpthread_private.a'))
-    elif base == 'libnacl_dyncode.a':
-      Log.Info('Not using IRT -- swapping private lib for libnacl_dyncode')
-      result_libs.append(pathtools.join(dname, 'libnacl_dyncode_private.a'))
-    else:
-      result_libs.append(l)
-  return result_libs
+def FixPrivateLibs(user_libs):
+  """If not using the IRT or if private libraries are used:
+    - Place private libraries that can coexist before their public
+      equivalent (keep both);
+    - Replace public libraries that can't coexist with their private
+      equivalent.
 
-def ReorderPrivateLibs(libs):
-  """ Place private libraries just before their non-private equivalent
-  if there is one.
+  This occurs before path resolution (important because public/private
+  libraries aren't always colocated) and assumes that -l:libfoo.a syntax
+  isn't used by the driver for relevant libraries.
   """
-  result_libs = list(libs)
-  bases = {}
-  for l in libs:
-    bases[pathtools.basename(l)] = l
-  lib_map = {
-      'libnacl_sys_private.a': 'libnacl.a',
-      'libpthread_private.a': 'libpthread.a',
-      'libnacl_dyncode_private.a': 'libnacl_dyncode.a'
+  special_libs = {
+      # Public library name: (private library name, can coexist?)
+      '-lnacl': ('-lnacl_sys_private', True),
+      '-lpthread': ('-lpthread_private', False),
       }
-  for l in libs:
-    base = pathtools.basename(l)
-    if base in lib_map and lib_map[base] in bases:
-      result_libs.remove(l)
-      result_libs.insert(result_libs.index(bases[lib_map[base]]), l)
+  private_libs = [v[0] for v in special_libs.values()]
+  public_libs = special_libs.keys()
+  private_lib_for = lambda user_lib: special_libs[user_lib][0]
+  can_coexist = lambda user_lib: special_libs[user_lib][1]
+
+  no_irt = not env.getbool('USE_IRT')
+  uses_private_libs = set(user_libs) & set(private_libs)
+
+  if not (no_irt or uses_private_libs):
+    return user_libs
+
+  result_libs = []
+  for user_lib in user_libs:
+    if user_lib in public_libs:
+      result_libs.append(private_lib_for(user_lib))
+      if can_coexist(user_lib):
+        result_libs.append(user_lib)
+    else:
+      result_libs.append(user_lib)
   return result_libs
 
 def SplitLinkLine(inputs):
@@ -543,7 +547,7 @@ def CheckInputsArch(inputs):
       ArchMerge(f, True)
     else:
       Log.Fatal("%s: Unexpected type of file for linking (%s)",
-                pathtools.touser(f), FileType(f))
+                pathtools.touser(f), filetype.FileType(f))
     count += 1
 
   if count == 0:
@@ -553,17 +557,9 @@ def DoLLVMPasses(pass_list):
   def Func(infile, outfile):
     filtered_list = [pass_option for pass_option in pass_list
                      if pass_option not in env.get('LLVM_PASSES_TO_DISABLE')]
-    RunDriver('opt', filtered_list + [infile, '-o', outfile])
+    RunDriver('pnacl-opt', filtered_list + [infile, '-o', outfile])
   return Func
 
-def DoLTO(infile, outfile):
-  opt_flags = env.get('OPT_FLAGS')
-  RunDriver('opt', opt_flags + [ infile, '-o', outfile ])
-
-def DoStrip(infile, outfile):
-  strip_flags = env.get('STRIP_FLAGS')
-  RunDriver('strip', strip_flags + [ infile, '-o', outfile ])
-
 def DoTranslate(infile, outfile):
   args = env.get('TRANSLATE_FLAGS')
   args += ['-Wl,'+s for s in env.get('LD_FLAGS_NATIVE')]
@@ -572,7 +568,7 @@ def DoTranslate(infile, outfile):
   args += ['-Wl,'+s if ldtools.IsFlag(s) else s
            for s in env.get('NATIVE_OBJECTS')]
   args += ['-o', outfile]
-  RunDriver('translate', args)
+  RunDriver('pnacl-translate', args)
 
 def LinkBC(inputs, output):
   '''Input: a bunch of bc/o/lib input files
@@ -588,7 +584,7 @@ def get_help(unused_argv):
 
 Bitcode linker for PNaCl.  Similar to the binutils "ld" tool,
 but links bitcode instead of native code.  Supports many of the
-"ld" flags.
+"ld" flags. Below are a subset of them.
 
 OPTIONS:
 
@@ -597,7 +593,7 @@ OPTIONS:
   -L DIRECTORY, --library-path DIRECTORY
                               Add DIRECTORY to library search path
 
-  -r, --relocatable           Generate relocatable output
+  -r, -relocatable            Generate relocatable output
 
   -O<opt-level>               Optimize output file
   -M, --print-map             Print map file on standard output
@@ -605,7 +601,7 @@ OPTIONS:
   --no-whole-archive          Turn off --whole-archive
   -s, --strip-all             Strip all symbols
   -S, --strip-debug           Strip debugging symbols
-  --undefined SYMBOL          Start with undefined reference to SYMBOL
+  -u SYM, --undefined=SYM     Start with undefined reference to SYM
 
   -help | -h                  Output this help.
 """