1#!/usr/bin/env python 2# 3# Copyright 2021 Espressif Systems (Shanghai) CO LTD 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16# 17 18import sys 19import unittest 20 21try: 22 from output_commands import AlignAtAddress, InputSectionDesc, SymbolAtAddress 23except ImportError: 24 sys.path.append('../') 25 from output_commands import InputSectionDesc, SymbolAtAddress, AlignAtAddress 26 27from entity import Entity 28 29SECTIONS = ['.text', '.text.*', '.literal', '.literal.*'] 30 31FREERTOS = Entity('libfreertos.a') 32CROUTINE = Entity('libfreertos.a', 'croutine') 33 34 35class InputSectionDescTest(unittest.TestCase): 36 37 def test_catch_all_placement(self): 38 # Test default (catch-all) command 39 expected = '*(.literal .literal.* .text .text.*)' 40 41 desc = InputSectionDesc(Entity(), SECTIONS) 42 self.assertEqual(expected, str(desc)) 43 44 desc = InputSectionDesc(Entity(Entity.ALL), SECTIONS) 45 self.assertEqual(expected, str(desc)) 46 47 def test_lib_placement(self): 48 # Test library placement command 49 expected = '*libfreertos.a:(.literal .literal.* .text .text.*)' 50 51 desc = InputSectionDesc(Entity('libfreertos.a'), SECTIONS) 52 self.assertEqual(expected, str(desc)) 53 54 desc = InputSectionDesc(Entity('libfreertos.a', Entity.ALL), SECTIONS) 55 self.assertEqual(expected, str(desc)) 56 57 desc = InputSectionDesc(Entity('libfreertos.a', None, Entity.ALL), SECTIONS) 58 self.assertEqual(expected, str(desc)) 59 60 desc = InputSectionDesc(Entity('libfreertos.a', Entity.ALL, Entity.ALL), SECTIONS) 61 self.assertEqual(expected, str(desc)) 62 63 def test_obj_placement(self): 64 # Test object placement command 65 expected = '*libfreertos.a:croutine.*(.literal .literal.* .text .text.*)' 66 67 desc = InputSectionDesc(Entity('libfreertos.a', 'croutine'), SECTIONS) 68 self.assertEqual(expected, str(desc)) 69 70 desc = InputSectionDesc(Entity('libfreertos.a', 'croutine'), SECTIONS) 71 self.assertEqual(expected, str(desc)) 72 73 desc = InputSectionDesc(Entity('libfreertos.a', 'croutine', Entity.ALL), SECTIONS) 74 self.assertEqual(expected, str(desc)) 75 76 # Disambugated placement 77 expected = '*libfreertos.a:croutine.c.*(.literal .literal.* .text .text.*)' 78 79 desc = InputSectionDesc(Entity('libfreertos.a', 'croutine.c'), SECTIONS) 80 self.assertEqual(expected, str(desc)) 81 82 def test_invalid_entity(self): 83 # Invalid entity specification 84 with self.assertRaises(AssertionError): 85 InputSectionDesc(Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList'), SECTIONS) 86 87 with self.assertRaises(AssertionError): 88 InputSectionDesc(Entity('libfreertos.a', 'croutine'), SECTIONS, [Entity()]) 89 90 with self.assertRaises(AssertionError): 91 InputSectionDesc(Entity('libfreertos.a', 'croutine'), SECTIONS, [Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList')]) 92 93 def test_exclusions(self): 94 # Test exclusions 95 96 # Library 97 expected = ('*libfreertos.a:croutine.*' 98 '(EXCLUDE_FILE(*libfreertos.a) ' 99 '.literal EXCLUDE_FILE(*libfreertos.a) ' 100 '.literal.* EXCLUDE_FILE(*libfreertos.a) ' 101 '.text EXCLUDE_FILE(*libfreertos.a) .text.*)') 102 desc = InputSectionDesc(CROUTINE, SECTIONS, [FREERTOS]) 103 self.assertEqual(expected, str(desc)) 104 105 # Object 106 expected = ('*libfreertos.a:croutine.*' 107 '(EXCLUDE_FILE(*libfreertos.a:croutine.*) ' 108 '.literal EXCLUDE_FILE(*libfreertos.a:croutine.*) ' 109 '.literal.* EXCLUDE_FILE(*libfreertos.a:croutine.*) ' 110 '.text EXCLUDE_FILE(*libfreertos.a:croutine.*) .text.*)') 111 desc = InputSectionDesc(CROUTINE, SECTIONS, [CROUTINE]) 112 self.assertEqual(expected, str(desc)) 113 114 # Multiple exclusions 115 expected = ('*libfreertos.a:croutine.*' 116 '(EXCLUDE_FILE(*libfreertos.a *libfreertos.a:croutine.*) ' 117 '.literal EXCLUDE_FILE(*libfreertos.a *libfreertos.a:croutine.*) ' 118 '.literal.* EXCLUDE_FILE(*libfreertos.a *libfreertos.a:croutine.*) ' 119 '.text EXCLUDE_FILE(*libfreertos.a *libfreertos.a:croutine.*) .text.*)') 120 desc = InputSectionDesc(CROUTINE, SECTIONS, [FREERTOS, CROUTINE]) 121 self.assertEqual(expected, str(desc)) 122 123 # Disambugated exclusion 124 expected = ('*libfreertos.a:croutine.*' 125 '(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) ' 126 '.literal EXCLUDE_FILE(*libfreertos.a:croutine.c.*) ' 127 '.literal.* EXCLUDE_FILE(*libfreertos.a:croutine.c.*) ' 128 '.text EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text.*)') 129 desc = InputSectionDesc(CROUTINE, SECTIONS, [Entity('libfreertos.a', 'croutine.c')]) 130 self.assertEqual(expected, str(desc)) 131 132 def test_empty_sections(self): 133 # Test empty sections 134 expected = '*libfreertos.a:croutine.*( )' 135 136 desc = InputSectionDesc(Entity('libfreertos.a', 'croutine'), []) 137 self.assertEqual(expected, str(desc)) 138 139 def test_keep(self): 140 # Test KEEP 141 expected = 'KEEP(*libfreertos.a:croutine.*( ))' 142 143 desc = InputSectionDesc(Entity('libfreertos.a', 'croutine'), [], keep=True) 144 self.assertEqual(expected, str(desc)) 145 146 def test_sort(self): 147 # Test sort 148 expected = ('*libfreertos.a:croutine.*(' 149 'SORT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal) ' 150 'SORT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal.*) ' 151 'SORT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text) ' 152 'SORT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text.*)' 153 ')') 154 desc = InputSectionDesc(CROUTINE, SECTIONS, [Entity('libfreertos.a', 'croutine.c')], keep=False, sort=(None, None)) 155 self.assertEqual(expected, str(desc)) 156 157 expected = ('*libfreertos.a:croutine.*(' 158 'SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal) ' 159 'SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal.*) ' 160 'SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text) ' 161 'SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text.*)' 162 ')') 163 desc = InputSectionDesc(CROUTINE, SECTIONS, [Entity('libfreertos.a', 'croutine.c')], keep=False, sort=('name', None)) 164 self.assertEqual(expected, str(desc)) 165 166 expected = ('*libfreertos.a:croutine.*(' 167 'SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal) ' 168 'SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal.*) ' 169 'SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text) ' 170 'SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text.*)' 171 ')') 172 desc = InputSectionDesc(CROUTINE, SECTIONS, [Entity('libfreertos.a', 'croutine.c')], keep=False, sort=('alignment', None)) 173 self.assertEqual(expected, str(desc)) 174 175 expected = ('*libfreertos.a:croutine.*(' 176 'SORT_BY_INIT_PRIORITY(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal) ' 177 'SORT_BY_INIT_PRIORITY(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal.*) ' 178 'SORT_BY_INIT_PRIORITY(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text) ' 179 'SORT_BY_INIT_PRIORITY(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text.*)' 180 ')') 181 desc = InputSectionDesc(CROUTINE, SECTIONS, [Entity('libfreertos.a', 'croutine.c')], keep=False, sort=('init_priority', None)) 182 self.assertEqual(expected, str(desc)) 183 184 expected = ('*libfreertos.a:croutine.*(' 185 'SORT_BY_NAME(SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal)) ' 186 'SORT_BY_NAME(SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal.*)) ' 187 'SORT_BY_NAME(SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text)) ' 188 'SORT_BY_NAME(SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text.*))' 189 ')') 190 desc = InputSectionDesc(CROUTINE, SECTIONS, [Entity('libfreertos.a', 'croutine.c')], keep=False, sort=('name', 'alignment')) 191 self.assertEqual(expected, str(desc)) 192 193 expected = ('*libfreertos.a:croutine.*(' 194 'SORT_BY_NAME(SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal)) ' 195 'SORT_BY_NAME(SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal.*)) ' 196 'SORT_BY_NAME(SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text)) ' 197 'SORT_BY_NAME(SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text.*))' 198 ')') 199 desc = InputSectionDesc(CROUTINE, SECTIONS, [Entity('libfreertos.a', 'croutine.c')], keep=False, sort=('name', 'name')) 200 self.assertEqual(expected, str(desc)) 201 202 expected = ('*libfreertos.a:croutine.*(' 203 'SORT_BY_ALIGNMENT(SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal)) ' 204 'SORT_BY_ALIGNMENT(SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal.*)) ' 205 'SORT_BY_ALIGNMENT(SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text)) ' 206 'SORT_BY_ALIGNMENT(SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text.*))' 207 ')') 208 desc = InputSectionDesc(CROUTINE, SECTIONS, [Entity('libfreertos.a', 'croutine.c')], keep=False, sort=('alignment', 'name')) 209 self.assertEqual(expected, str(desc)) 210 211 expected = ('*libfreertos.a:croutine.*(' 212 'SORT_BY_ALIGNMENT(SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal)) ' 213 'SORT_BY_ALIGNMENT(SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal.*)) ' 214 'SORT_BY_ALIGNMENT(SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text)) ' 215 'SORT_BY_ALIGNMENT(SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text.*))' 216 ')') 217 desc = InputSectionDesc(CROUTINE, SECTIONS, [Entity('libfreertos.a', 'croutine.c')], keep=False, sort=('alignment', 'alignment')) 218 self.assertEqual(expected, str(desc)) 219 220 221class SymbolAtAddressTest(unittest.TestCase): 222 223 def test_symbol(self): 224 symbol = 'test_symbol' 225 expected = '%s = ABSOLUTE(.);' % symbol 226 227 desc = SymbolAtAddress(symbol) 228 self.assertEqual(expected, str(desc)) 229 230 231class AlignAtAddressTest(unittest.TestCase): 232 233 def test_align(self): 234 align = 8 235 expected = '. = ALIGN(%d);' % 8 236 237 desc = AlignAtAddress(align) 238 self.assertEqual(expected, str(desc)) 239 240 241if __name__ == '__main__': 242 unittest.main() 243