blob: fb6e451cf0ec181070d9c4bea3ffb33a4fceac50 [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001# SPDX-License-Identifier: GPL-2.0+
Simon Glassb50e5612017-11-13 18:54:54 -07002# Copyright (c) 2017 Google, Inc
3# Written by Simon Glass <sjg@chromium.org>
4#
Simon Glassb50e5612017-11-13 18:54:54 -07005# Test for the elf module
6
Simon Glass19790632017-11-13 18:55:01 -07007from contextlib import contextmanager
Simon Glassb50e5612017-11-13 18:54:54 -07008import os
9import sys
10import unittest
11
Simon Glass19790632017-11-13 18:55:01 -070012try:
13 from StringIO import StringIO
14except ImportError:
15 from io import StringIO
16
Simon Glassb50e5612017-11-13 18:54:54 -070017import elf
18
19binman_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
Simon Glass19790632017-11-13 18:55:01 -070020
21# Use this to suppress stdout/stderr output:
22# with capture_sys_output() as (stdout, stderr)
23# ...do something...
24@contextmanager
25def capture_sys_output():
26 capture_out, capture_err = StringIO(), StringIO()
27 old_out, old_err = sys.stdout, sys.stderr
28 try:
29 sys.stdout, sys.stderr = capture_out, capture_err
30 yield capture_out, capture_err
31 finally:
32 sys.stdout, sys.stderr = old_out, old_err
33
34
35class FakeEntry:
36 def __init__(self, contents_size):
37 self.contents_size = contents_size
38 self.data = 'a' * contents_size
39
40 def GetPath(self):
41 return 'entry_path'
42
Simon Glassf55382b2018-06-01 09:38:13 -060043class FakeSection:
Simon Glass19790632017-11-13 18:55:01 -070044 def __init__(self, sym_value=1):
45 self.sym_value = sym_value
46
47 def GetPath(self):
Simon Glassf55382b2018-06-01 09:38:13 -060048 return 'section_path'
Simon Glass19790632017-11-13 18:55:01 -070049
50 def LookupSymbol(self, name, weak, msg):
51 return self.sym_value
Simon Glassb50e5612017-11-13 18:54:54 -070052
53class TestElf(unittest.TestCase):
54 def testAllSymbols(self):
Simon Glass19790632017-11-13 18:55:01 -070055 fname = os.path.join(binman_dir, 'test', 'u_boot_ucode_ptr')
Simon Glassb50e5612017-11-13 18:54:54 -070056 syms = elf.GetSymbols(fname, [])
57 self.assertIn('.ucode', syms)
58
59 def testRegexSymbols(self):
Simon Glass19790632017-11-13 18:55:01 -070060 fname = os.path.join(binman_dir, 'test', 'u_boot_ucode_ptr')
Simon Glassb50e5612017-11-13 18:54:54 -070061 syms = elf.GetSymbols(fname, ['ucode'])
62 self.assertIn('.ucode', syms)
63 syms = elf.GetSymbols(fname, ['missing'])
64 self.assertNotIn('.ucode', syms)
65 syms = elf.GetSymbols(fname, ['missing', 'ucode'])
66 self.assertIn('.ucode', syms)
67
Simon Glass19790632017-11-13 18:55:01 -070068 def testMissingFile(self):
69 entry = FakeEntry(10)
Simon Glassf55382b2018-06-01 09:38:13 -060070 section = FakeSection()
Simon Glass19790632017-11-13 18:55:01 -070071 with self.assertRaises(ValueError) as e:
Simon Glassf55382b2018-06-01 09:38:13 -060072 syms = elf.LookupAndWriteSymbols('missing-file', entry, section)
Simon Glass19790632017-11-13 18:55:01 -070073 self.assertIn("Filename 'missing-file' not found in input path",
74 str(e.exception))
75
76 def testOutsideFile(self):
77 entry = FakeEntry(10)
Simon Glassf55382b2018-06-01 09:38:13 -060078 section = FakeSection()
Simon Glass19790632017-11-13 18:55:01 -070079 elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms')
80 with self.assertRaises(ValueError) as e:
Simon Glassf55382b2018-06-01 09:38:13 -060081 syms = elf.LookupAndWriteSymbols(elf_fname, entry, section)
Simon Glass19790632017-11-13 18:55:01 -070082 self.assertIn('entry_path has offset 4 (size 8) but the contents size '
83 'is a', str(e.exception))
84
85 def testMissingImageStart(self):
86 entry = FakeEntry(10)
Simon Glassf55382b2018-06-01 09:38:13 -060087 section = FakeSection()
Simon Glass19790632017-11-13 18:55:01 -070088 elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms_bad')
Simon Glassf55382b2018-06-01 09:38:13 -060089 self.assertEqual(elf.LookupAndWriteSymbols(elf_fname, entry, section),
Simon Glass19790632017-11-13 18:55:01 -070090 None)
91
92 def testBadSymbolSize(self):
93 entry = FakeEntry(10)
Simon Glassf55382b2018-06-01 09:38:13 -060094 section = FakeSection()
Simon Glass19790632017-11-13 18:55:01 -070095 elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms_size')
96 with self.assertRaises(ValueError) as e:
Simon Glassf55382b2018-06-01 09:38:13 -060097 syms = elf.LookupAndWriteSymbols(elf_fname, entry, section)
Simon Glass19790632017-11-13 18:55:01 -070098 self.assertIn('has size 1: only 4 and 8 are supported',
99 str(e.exception))
100
101 def testNoValue(self):
102 entry = FakeEntry(20)
Simon Glassf55382b2018-06-01 09:38:13 -0600103 section = FakeSection(sym_value=None)
Simon Glass19790632017-11-13 18:55:01 -0700104 elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms')
Simon Glassf55382b2018-06-01 09:38:13 -0600105 syms = elf.LookupAndWriteSymbols(elf_fname, entry, section)
Simon Glass19790632017-11-13 18:55:01 -0700106 self.assertEqual(chr(255) * 16 + 'a' * 4, entry.data)
107
108 def testDebug(self):
109 elf.debug = True
110 entry = FakeEntry(20)
Simon Glassf55382b2018-06-01 09:38:13 -0600111 section = FakeSection()
Simon Glass19790632017-11-13 18:55:01 -0700112 elf_fname = os.path.join(binman_dir, 'test', 'u_boot_binman_syms')
113 with capture_sys_output() as (stdout, stderr):
Simon Glassf55382b2018-06-01 09:38:13 -0600114 syms = elf.LookupAndWriteSymbols(elf_fname, entry, section)
Simon Glass19790632017-11-13 18:55:01 -0700115 elf.debug = False
116 self.assertTrue(len(stdout.getvalue()) > 0)
117
118
Simon Glassb50e5612017-11-13 18:54:54 -0700119if __name__ == '__main__':
120 unittest.main()