#!/usr/bin/env python
from __future__ import print_function
'''
Helper script to print out the raw content of an ELF section.
Example usages:
```
# print out as bits by default
extract-section.py .text --input-file=foo.o
```
```
# read from stdin and print out in hex
cat foo.o | extract-section.py -h .text
```
This is merely a wrapper around `llvm-readobj` that focuses on the binary
content as well as providing more formatting options.
'''

# Unfortunately reading binary from stdin is not so trivial in Python...
def read_raw_stdin():
    import sys
    if sys.version_info >= (3, 0):
        reading_source = sys.stdin.buffer
    else:
        # Windows will always read as string so we need some
        # special handling
        if sys.platform == 'win32':
            import os, msvcrt
            msvcrt.setformat(sys.stdin.fileno(), os.O_BINARY)
        reading_source = sys.stdin
    return reading_source.read()

def get_raw_section_dump(readobj_path, section_name, input_file):
    import subprocess
    cmd = [readobj_path, '-elf-output-style=GNU', '--hex-dump={}'.format(section_name),
            input_file]
    proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)

    if input_file == '-':
        # From stdin
        out,_ = proc.communicate(input=read_raw_stdin())
    else:
        out,_ = proc.communicate()

    return out.decode('utf-8') if type(out) is not str else out

if __name__ == '__main__':
    import argparse
    # The default '-h' (--help) will conflict with our '-h' (hex) format
    arg_parser = argparse.ArgumentParser(add_help=False)
    arg_parser.add_argument('--readobj-path', metavar='<executable path>', type=str,
            help='Path to llvm-readobj')
    arg_parser.add_argument('--input-file', metavar='<file>', type=str,
            help='Input object file, or \'-\' to read from stdin')
    arg_parser.add_argument('section', metavar='<name>', type=str,
            help='Name of the section to extract')
    # Output format
    format_group = arg_parser.add_mutually_exclusive_group()
    format_group.add_argument('-b', dest='format', action='store_const', const='bits',
            help='Print out in bits')
    arg_parser.add_argument('--byte-indicator', action='store_true',
            help='Whether to print a \'.\' every 8 bits in bits printing mode')
    format_group.add_argument('-h', dest='format', action='store_const', const='hex',
            help='Print out in hexadecimal')
    arg_parser.add_argument('--hex-width', metavar='<# of bytes>', type=int,
            help='The width (in byte) of every element in hex printing mode')

    arg_parser.add_argument('--help', action='help')
    arg_parser.set_defaults(format='bits', tool_path='llvm-readobj', input_file='-',
            byte_indicator=False, hex_width=4)
    args = arg_parser.parse_args()

    raw_section = get_raw_section_dump(args.tool_path, args.section, args.input_file)

    results = []
    for line in raw_section.splitlines(False):
        if line.startswith('Hex dump'):
            continue
        parts = line.strip().split(' ')[1:]
        for part in parts[:4]:
            # exclude any non-hex dump string
            try:
                val = int(part, 16)
                if args.format == 'bits':
                    # divided into bytes first
                    for byte in [(val >> off) & 0xFF for off in (24,16,8,0)]:
                        for bit in [(byte >> off) & 1 for off in range(7, -1, -1)]:
                            results.append(str(bit))
                        if args.byte_indicator:
                            results.append('.')
                elif args.format == 'hex':
                    assert args.hex_width <= 4 and args.hex_width > 0
                    width_bits = args.hex_width * 8
                    offsets = [off for off in range(32 - width_bits, -1, -width_bits)]
                    mask = (1 << width_bits) - 1
                    format_str = "{:0" + str(args.hex_width * 2) + "x}"
                    for word in [(val >> i) & mask for i in offsets]:
                        results.append(format_str.format(word))
            except:
                break
    print(' '.join(results), end='')
