1#!/usr/bin/python 2 3# Copyright 2010 The Native Client Authors. All rights reserved. 4# Use of this source code is governed by a BSD-style license that can be 5# found in the LICENSE file. 6 7from __future__ import print_function 8 9import getopt 10import sys 11 12import elf 13 14USAGE = """Usage: elf_checker [options]* [filename]+ 15 16This tools verifies alignment attributes of segments in elf binaries. 17If no attribute is specified via '-a' each segment in the binary is dumped. 18Otherwise, all options must be specified. 19 20Options: 21 -a (vaddr|paddr|memsz|filesz): select the segement attribute to be checked 22 -s <name>: only consider segments with this name 23 -f <flag>: only consider segments with this flag value 24 -d <divisor> divide segment attribute by this number 25 -r <remainder> check division for this remainder 26""" 27 28 29def Fatal(mesg): 30 print(mesg, file=sys.stderr) 31 sys.exit(1) 32 33 34def DumpSegments(elf_obj): 35 for n, s in enumerate(elf_obj.PhdrList()): 36 print(n, str(s)) 37 38 39def CheckSegments(elf_obj, attribute, segment, flags, divisor, remainder): 40 def ismatch(s): 41 return s.TypeName() == segment and s.flags == flags 42 43 filtered_segments = [p for p in elf_obj.PhdrList() if ismatch(p)] 44 if not filtered_segments: 45 Fatal('no matching segments found') 46 47 for s in filtered_segments: 48 print('found: ', str(s)) 49 val = s.__dict__[attribute] 50 result = val % divisor 51 if result != remainder: 52 Fatal("%x %% %x == %x (expected %x)" % (val, divisor, result, remainder)) 53 54 55def main(argv): 56 try: 57 opts, args = getopt.getopt(argv[1:], 'a:s:d:r:f:') 58 except getopt.error, e: 59 Fatal(str(e) + '\n' + USAGE) 60 61 flags = None 62 remainder = None 63 divisor = None 64 attribute = None 65 segment = None 66 67 for opt, val in opts: 68 if opt == '-r': 69 remainder = int(val, 0) 70 elif opt == '-s': 71 segment = val 72 elif opt == '-d': 73 divisor = int(val, 0) 74 elif opt == '-a': 75 attribute = val 76 elif opt == '-f': 77 flags = int(val, 0) 78 else: 79 assert False 80 81 if not args: 82 Fatal('no files specified') 83 84 if attribute is not None: 85 if attribute not in ['vaddr', 'paddr', 'memsz', 'filesz']: 86 Fatal('unknown attribute: %s' % attribute) 87 if segment is None: 88 Fatal('you must specify a segment name via -s') 89 if flags is None: 90 Fatal('you must specify segment flags via -f') 91 if divisor is None: 92 Fatal('you must specify a divisor via -d') 93 if remainder is None: 94 Fatal('you must specify a remainder via -r') 95 96 for filename in args: 97 data = open(filename).read() 98 elf_obj = elf.Elf(data) 99 if attribute is None: 100 DumpSegments(elf_obj) 101 else: 102 CheckSegments(elf_obj, attribute, segment, flags, divisor, remainder) 103 104 return 0 105 106 107if __name__ == '__main__': 108 sys.exit(main(sys.argv)) 109