test_output_commands.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. #!/usr/bin/env python
  2. #
  3. # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  4. # SPDX-License-Identifier: Apache-2.0
  5. #
  6. import os
  7. import sys
  8. import unittest
  9. try:
  10. from ldgen.entity import Entity
  11. from ldgen.output_commands import AlignAtAddress, InputSectionDesc, SymbolAtAddress
  12. except ImportError:
  13. sys.path.append(os.path.dirname(os.path.dirname(__file__)))
  14. from ldgen.entity import Entity
  15. from ldgen.output_commands import AlignAtAddress, InputSectionDesc, SymbolAtAddress
  16. SECTIONS = ['.text', '.text.*', '.literal', '.literal.*']
  17. FREERTOS = Entity('libfreertos.a')
  18. CROUTINE = Entity('libfreertos.a', 'croutine')
  19. class InputSectionDescTest(unittest.TestCase):
  20. def test_catch_all_placement(self):
  21. # Test default (catch-all) command
  22. expected = '*(.literal .literal.* .text .text.*)'
  23. desc = InputSectionDesc(Entity(), SECTIONS)
  24. self.assertEqual(expected, str(desc))
  25. desc = InputSectionDesc(Entity(Entity.ALL), SECTIONS)
  26. self.assertEqual(expected, str(desc))
  27. def test_lib_placement(self):
  28. # Test library placement command
  29. expected = '*libfreertos.a:(.literal .literal.* .text .text.*)'
  30. desc = InputSectionDesc(Entity('libfreertos.a'), SECTIONS)
  31. self.assertEqual(expected, str(desc))
  32. desc = InputSectionDesc(Entity('libfreertos.a', Entity.ALL), SECTIONS)
  33. self.assertEqual(expected, str(desc))
  34. desc = InputSectionDesc(Entity('libfreertos.a', None, Entity.ALL), SECTIONS)
  35. self.assertEqual(expected, str(desc))
  36. desc = InputSectionDesc(Entity('libfreertos.a', Entity.ALL, Entity.ALL), SECTIONS)
  37. self.assertEqual(expected, str(desc))
  38. def test_obj_placement(self):
  39. # Test object placement command
  40. expected = '*libfreertos.a:croutine.*(.literal .literal.* .text .text.*)'
  41. desc = InputSectionDesc(Entity('libfreertos.a', 'croutine'), SECTIONS)
  42. self.assertEqual(expected, str(desc))
  43. desc = InputSectionDesc(Entity('libfreertos.a', 'croutine'), SECTIONS)
  44. self.assertEqual(expected, str(desc))
  45. desc = InputSectionDesc(Entity('libfreertos.a', 'croutine', Entity.ALL), SECTIONS)
  46. self.assertEqual(expected, str(desc))
  47. # Disambugated placement
  48. expected = '*libfreertos.a:croutine.c.*(.literal .literal.* .text .text.*)'
  49. desc = InputSectionDesc(Entity('libfreertos.a', 'croutine.c'), SECTIONS)
  50. self.assertEqual(expected, str(desc))
  51. def test_invalid_entity(self):
  52. # Invalid entity specification
  53. with self.assertRaises(AssertionError):
  54. InputSectionDesc(Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList'), SECTIONS)
  55. with self.assertRaises(AssertionError):
  56. InputSectionDesc(Entity('libfreertos.a', 'croutine'), SECTIONS, [Entity()])
  57. with self.assertRaises(AssertionError):
  58. InputSectionDesc(Entity('libfreertos.a', 'croutine'), SECTIONS, [Entity('libfreertos.a', 'croutine', 'prvCheckPendingReadyList')])
  59. def test_exclusions(self):
  60. # Test exclusions
  61. # Library
  62. expected = ('*libfreertos.a:croutine.*'
  63. '(EXCLUDE_FILE(*libfreertos.a) '
  64. '.literal EXCLUDE_FILE(*libfreertos.a) '
  65. '.literal.* EXCLUDE_FILE(*libfreertos.a) '
  66. '.text EXCLUDE_FILE(*libfreertos.a) .text.*)')
  67. desc = InputSectionDesc(CROUTINE, SECTIONS, [FREERTOS])
  68. self.assertEqual(expected, str(desc))
  69. # Object
  70. expected = ('*libfreertos.a:croutine.*'
  71. '(EXCLUDE_FILE(*libfreertos.a:croutine.*) '
  72. '.literal EXCLUDE_FILE(*libfreertos.a:croutine.*) '
  73. '.literal.* EXCLUDE_FILE(*libfreertos.a:croutine.*) '
  74. '.text EXCLUDE_FILE(*libfreertos.a:croutine.*) .text.*)')
  75. desc = InputSectionDesc(CROUTINE, SECTIONS, [CROUTINE])
  76. self.assertEqual(expected, str(desc))
  77. # Multiple exclusions
  78. expected = ('*libfreertos.a:croutine.*'
  79. '(EXCLUDE_FILE(*libfreertos.a *libfreertos.a:croutine.*) '
  80. '.literal EXCLUDE_FILE(*libfreertos.a *libfreertos.a:croutine.*) '
  81. '.literal.* EXCLUDE_FILE(*libfreertos.a *libfreertos.a:croutine.*) '
  82. '.text EXCLUDE_FILE(*libfreertos.a *libfreertos.a:croutine.*) .text.*)')
  83. desc = InputSectionDesc(CROUTINE, SECTIONS, [FREERTOS, CROUTINE])
  84. self.assertEqual(expected, str(desc))
  85. # Disambugated exclusion
  86. expected = ('*libfreertos.a:croutine.*'
  87. '(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) '
  88. '.literal EXCLUDE_FILE(*libfreertos.a:croutine.c.*) '
  89. '.literal.* EXCLUDE_FILE(*libfreertos.a:croutine.c.*) '
  90. '.text EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text.*)')
  91. desc = InputSectionDesc(CROUTINE, SECTIONS, [Entity('libfreertos.a', 'croutine.c')])
  92. self.assertEqual(expected, str(desc))
  93. def test_empty_sections(self):
  94. # Test empty sections
  95. expected = '*libfreertos.a:croutine.*( )'
  96. desc = InputSectionDesc(Entity('libfreertos.a', 'croutine'), [])
  97. self.assertEqual(expected, str(desc))
  98. def test_keep(self):
  99. # Test KEEP
  100. expected = 'KEEP(*libfreertos.a:croutine.*( ))'
  101. desc = InputSectionDesc(Entity('libfreertos.a', 'croutine'), [], keep=True)
  102. self.assertEqual(expected, str(desc))
  103. def test_sort(self):
  104. # Test sort
  105. expected = ('*libfreertos.a:croutine.*('
  106. 'SORT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal) '
  107. 'SORT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal.*) '
  108. 'SORT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text) '
  109. 'SORT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text.*)'
  110. ')')
  111. desc = InputSectionDesc(CROUTINE, SECTIONS, [Entity('libfreertos.a', 'croutine.c')], keep=False, sort=(None, None))
  112. self.assertEqual(expected, str(desc))
  113. expected = ('*libfreertos.a:croutine.*('
  114. 'SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal) '
  115. 'SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal.*) '
  116. 'SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text) '
  117. 'SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text.*)'
  118. ')')
  119. desc = InputSectionDesc(CROUTINE, SECTIONS, [Entity('libfreertos.a', 'croutine.c')], keep=False, sort=('name', None))
  120. self.assertEqual(expected, str(desc))
  121. expected = ('*libfreertos.a:croutine.*('
  122. 'SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal) '
  123. 'SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal.*) '
  124. 'SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text) '
  125. 'SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text.*)'
  126. ')')
  127. desc = InputSectionDesc(CROUTINE, SECTIONS, [Entity('libfreertos.a', 'croutine.c')], keep=False, sort=('alignment', None))
  128. self.assertEqual(expected, str(desc))
  129. expected = ('*libfreertos.a:croutine.*('
  130. 'SORT_BY_INIT_PRIORITY(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal) '
  131. 'SORT_BY_INIT_PRIORITY(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal.*) '
  132. 'SORT_BY_INIT_PRIORITY(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text) '
  133. 'SORT_BY_INIT_PRIORITY(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text.*)'
  134. ')')
  135. desc = InputSectionDesc(CROUTINE, SECTIONS, [Entity('libfreertos.a', 'croutine.c')], keep=False, sort=('init_priority', None))
  136. self.assertEqual(expected, str(desc))
  137. expected = ('*libfreertos.a:croutine.*('
  138. 'SORT_BY_NAME(SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal)) '
  139. 'SORT_BY_NAME(SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal.*)) '
  140. 'SORT_BY_NAME(SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text)) '
  141. 'SORT_BY_NAME(SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text.*))'
  142. ')')
  143. desc = InputSectionDesc(CROUTINE, SECTIONS, [Entity('libfreertos.a', 'croutine.c')], keep=False, sort=('name', 'alignment'))
  144. self.assertEqual(expected, str(desc))
  145. expected = ('*libfreertos.a:croutine.*('
  146. 'SORT_BY_NAME(SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal)) '
  147. 'SORT_BY_NAME(SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal.*)) '
  148. 'SORT_BY_NAME(SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text)) '
  149. 'SORT_BY_NAME(SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text.*))'
  150. ')')
  151. desc = InputSectionDesc(CROUTINE, SECTIONS, [Entity('libfreertos.a', 'croutine.c')], keep=False, sort=('name', 'name'))
  152. self.assertEqual(expected, str(desc))
  153. expected = ('*libfreertos.a:croutine.*('
  154. 'SORT_BY_ALIGNMENT(SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal)) '
  155. 'SORT_BY_ALIGNMENT(SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal.*)) '
  156. 'SORT_BY_ALIGNMENT(SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text)) '
  157. 'SORT_BY_ALIGNMENT(SORT_BY_NAME(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text.*))'
  158. ')')
  159. desc = InputSectionDesc(CROUTINE, SECTIONS, [Entity('libfreertos.a', 'croutine.c')], keep=False, sort=('alignment', 'name'))
  160. self.assertEqual(expected, str(desc))
  161. expected = ('*libfreertos.a:croutine.*('
  162. 'SORT_BY_ALIGNMENT(SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal)) '
  163. 'SORT_BY_ALIGNMENT(SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .literal.*)) '
  164. 'SORT_BY_ALIGNMENT(SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text)) '
  165. 'SORT_BY_ALIGNMENT(SORT_BY_ALIGNMENT(EXCLUDE_FILE(*libfreertos.a:croutine.c.*) .text.*))'
  166. ')')
  167. desc = InputSectionDesc(CROUTINE, SECTIONS, [Entity('libfreertos.a', 'croutine.c')], keep=False, sort=('alignment', 'alignment'))
  168. self.assertEqual(expected, str(desc))
  169. class SymbolAtAddressTest(unittest.TestCase):
  170. def test_symbol(self):
  171. symbol = 'test_symbol'
  172. expected = '%s = ABSOLUTE(.);' % symbol
  173. desc = SymbolAtAddress(symbol)
  174. self.assertEqual(expected, str(desc))
  175. class AlignAtAddressTest(unittest.TestCase):
  176. def test_align(self):
  177. align = 8
  178. expected = '. = ALIGN(%d);' % 8
  179. desc = AlignAtAddress(align)
  180. self.assertEqual(expected, str(desc))
  181. if __name__ == '__main__':
  182. unittest.main()