OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 # Copyright (c) 2012 The Native Client Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 # | 5 # |
6 # IMPORTANT NOTE: If you make local mods to this file, you must run: | 6 # IMPORTANT NOTE: If you make local mods to this file, you must run: |
7 # % tools/llvm/utman.sh driver | 7 # % pnacl/build.sh driver |
8 # in order for them to take effect in the scons build. This command | 8 # in order for them to take effect in the scons build. This command |
9 # updates the copy in the toolchain/ tree. | 9 # updates the copy in the toolchain/ tree. |
10 # | 10 # |
11 | 11 |
12 # Show the PNaCl metadata of a bitcode file | 12 # Show the PNaCl metadata of a bitcode file (which mirror ELF information). |
13 | 13 |
14 from driver_tools import * | 14 from driver_tools import * |
15 from driver_env import env | 15 from driver_env import env |
16 from driver_log import Log, DriverExit | 16 from driver_log import Log, DriverExit |
17 | 17 |
| 18 K_NEEDS_KEY = 'NeedsLibrary' |
| 19 |
| 20 def OutputLddFormat(input_file, metadata): |
| 21 ''' Dump NEEDED dependencies in the ldd style output format. |
| 22 lib1 => path1 (0xaddress). |
| 23 However, we use dummy paths and addresses. |
| 24 ''' |
| 25 needed = metadata[K_NEEDS_KEY] |
| 26 dummy_path = '/dummy_path' |
| 27 for (index, lib) in enumerate(needed): |
| 28 dummy_address = 0xdeadbeef + index |
| 29 print '\t%s => %s/%s (0x%x)' % (lib, |
| 30 dummy_path, |
| 31 lib, |
| 32 dummy_address) |
| 33 |
| 34 |
| 35 def OutputObjdumpFormat(input_file, metadata): |
| 36 '''Dump NEEDED dependencies in the objdump -p output format. |
| 37 Most of the objdump -p output will be faked. |
| 38 Only the NEEDED entries will be reliable. |
| 39 ''' |
| 40 needed = metadata[K_NEEDS_KEY] |
| 41 print '%s: file format le32-bitcode' % (pathtools.touser(input_file)) |
| 42 needed_string = '\n'.join( |
| 43 [ ' NEEDED\t\t%s' % libname for libname in needed ]) |
| 44 print ''' |
| 45 Program Header: |
| 46 No program header info. |
| 47 |
| 48 Dynamic Section: |
| 49 %s |
| 50 Other bits not available. |
| 51 |
| 52 Version References: |
| 53 No version info. |
| 54 |
| 55 ''' % needed_string |
| 56 |
| 57 |
| 58 def OutputPnaclFormat(input_file, metadata): |
| 59 '''Dump NEEDED dependencies in the custom pnacl output format. |
| 60 ''' |
| 61 print pathtools.touser(input_file) + ":" |
| 62 for k, v in metadata.iteritems(): |
| 63 if isinstance(v, list): |
| 64 v = "[ " + ', '.join(v) + " ]" |
| 65 print " %-12s: %s" % (k, v) |
| 66 |
| 67 |
| 68 ''' Supported output formats { mode : (description, outputter_function) } ''' |
| 69 OUTPUT_FORMATS = { |
| 70 'ldd' : |
| 71 ('ldd-style output format (with dummy load addresses / file paths).', |
| 72 OutputLddFormat), |
| 73 'objdump' : |
| 74 ('objdump -p style output format (NEEDED xxx)', |
| 75 OutputObjdumpFormat), |
| 76 'pnacl' : |
| 77 ('custom pnacl output format', |
| 78 OutputPnaclFormat), |
| 79 } |
| 80 |
18 EXTRA_ENV = { | 81 EXTRA_ENV = { |
19 'INPUTS' : '', | 82 'INPUTS' : '', |
| 83 'OUTPUT_FORMAT' : 'pnacl', |
20 } | 84 } |
21 env.update(EXTRA_ENV) | 85 env.update(EXTRA_ENV) |
22 | 86 |
23 META_PATTERNS = [ | 87 META_PATTERNS = [ |
| 88 ( '--format=(.*)', "env.set('OUTPUT_FORMAT', $0)"), |
24 ( '(.*)', "env.append('INPUTS', pathtools.normalize($0))"), | 89 ( '(.*)', "env.append('INPUTS', pathtools.normalize($0))"), |
25 ] | 90 ] |
26 | 91 |
27 def Usage(): | 92 def Usage(): |
28 print "Usage: pnacl-meta [files...]" | 93 print "Usage: pnacl-meta [files...] [--format={ldd, objdump, pnacl}]" |
29 print "Show the PNaCl-specific metadata of a bitcode file" | 94 print "Show the PNaCl-specific metadata of a bitcode file" |
30 | 95 |
| 96 |
| 97 def CheckOutputFormat(out_format): |
| 98 if out_format not in OUTPUT_FORMATS.keys(): |
| 99 possible_formats = '\n'.join([ ('\t%s:\t%s' % (key, desc)) |
| 100 for (key, (desc, _)) |
| 101 in OUTPUT_FORMATS.items() ]) |
| 102 Log.Fatal('--format is currently %s.\nIt must be one of the following:\n%s', |
| 103 out_format, possible_formats) |
| 104 _, outputter = OUTPUT_FORMATS[out_format] |
| 105 return outputter |
| 106 |
31 def main(argv): | 107 def main(argv): |
32 ParseArgs(argv, META_PATTERNS) | 108 ParseArgs(argv, META_PATTERNS) |
33 | 109 out_format = env.getone('OUTPUT_FORMAT') |
| 110 outputter = CheckOutputFormat(out_format) |
34 inputs = env.get('INPUTS') | 111 inputs = env.get('INPUTS') |
35 | 112 |
36 if not inputs: | 113 if not inputs: |
37 Usage() | 114 Usage() |
38 DriverExit(0) | 115 DriverExit(0) |
39 | 116 |
40 for f in inputs: | 117 for f in inputs: |
41 if not IsBitcode(f): | 118 if not IsBitcode(f): |
42 Log.Fatal("%s: File is not bitcode", pathtools.touser(f)) | 119 Log.Fatal("%s: File is not bitcode", pathtools.touser(f)) |
43 metadata = GetBitcodeMetadata(f) | 120 metadata = GetBitcodeMetadata(f) |
44 print pathtools.touser(f) + ":" | 121 outputter(f, metadata) |
45 for k, v in metadata.iteritems(): | |
46 if isinstance(v, list): | |
47 v = "[ " + ', '.join(v) + " ]" | |
48 print " %-12s: %s" % (k, v) | |
49 | 122 |
50 return 0 | 123 return 0 |
51 | 124 |
52 if __name__ == "__main__": | 125 if __name__ == "__main__": |
53 DriverMain(main) | 126 DriverMain(main) |
OLD | NEW |