output_commands.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #
  2. # Copyright 2021 Espressif Systems (Shanghai) CO LTD
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. #
  16. from entity import Entity
  17. # Contains classes for output section commands referred to in
  18. # https://www.acrc.bris.ac.uk/acrc/RedHat/rhel-ld-en-4/sections.html#OUTPUT-SECTION-DESCRIPTION.
  19. class AlignAtAddress():
  20. """
  21. Outputs assignment of builtin function ALIGN to current
  22. position:
  23. . = ALIGN(<alignment>)
  24. Mapping fragment flag ALIGN causes this output section
  25. command to be emitted.
  26. """
  27. def __init__(self, alignment):
  28. self.alignment = alignment
  29. def __str__(self):
  30. return ('. = ALIGN(%d);' % self.alignment)
  31. def __eq__(self, other):
  32. return (isinstance(other, AlignAtAddress) and
  33. self.alignment == other.alignment)
  34. class SymbolAtAddress():
  35. """
  36. Outputs assignment of builtin function ABSOLUTE to a symbol
  37. for current position:
  38. <symbol> = ABSOLUTE(.)
  39. Mapping fragment flag SURROUND causes this
  40. output section command to be emitted before and after
  41. an InputSectionDesc.
  42. """
  43. def __init__(self, symbol):
  44. self.symbol = symbol
  45. def __str__(self):
  46. return ('%s = ABSOLUTE(.);' % self.symbol)
  47. def __eq__(self, other):
  48. return (isinstance(other, SymbolAtAddress) and
  49. self.symbol == other.symbol)
  50. class InputSectionDesc():
  51. """
  52. Outputs an input section description as described in
  53. https://www.acrc.bris.ac.uk/acrc/RedHat/rhel-ld-en-4/sections.html#INPUT-SECTION.
  54. These commands are emmited from mapping fragment entries, specifically attaching
  55. a scheme onto an entity. Mapping fragment flags KEEP, SORT will also affect
  56. the emitted input section description.
  57. """
  58. def __init__(self, entity, sections, exclusions=None, keep=False, sort=None):
  59. assert(entity.specificity != Entity.Specificity.SYMBOL)
  60. self.entity = entity
  61. self.sections = set(sections)
  62. self.exclusions = set()
  63. if exclusions:
  64. assert(not [e for e in exclusions if e.specificity == Entity.Specificity.SYMBOL or
  65. e.specificity == Entity.Specificity.NONE])
  66. self.exclusions = set(exclusions)
  67. else:
  68. self.exclusions = set()
  69. self.keep = keep
  70. self.sort = sort
  71. def __str__(self):
  72. sections_string = '( )'
  73. if self.sections:
  74. exclusion_strings = []
  75. for exc in sorted(self.exclusions):
  76. if exc.specificity == Entity.Specificity.ARCHIVE:
  77. exc_string = '*%s' % (exc.archive)
  78. else:
  79. exc_string = '*%s:%s.*' % (exc.archive, exc.obj)
  80. exclusion_strings.append(exc_string)
  81. section_strings = []
  82. if exclusion_strings:
  83. exclusion_string = 'EXCLUDE_FILE(%s)' % ' '.join(exclusion_strings)
  84. for section in sorted(self.sections):
  85. section_strings.append('%s %s' % (exclusion_string, section))
  86. else:
  87. for section in sorted(self.sections):
  88. section_strings.append(section)
  89. if self.sort:
  90. if self.sort == (None, None):
  91. pattern = 'SORT(%s)'
  92. elif self.sort == ('name', None):
  93. pattern = 'SORT_BY_NAME(%s)'
  94. elif self.sort == ('alignment', None):
  95. pattern = 'SORT_BY_ALIGNMENT(%s)'
  96. elif self.sort == ('init_priority', None):
  97. pattern = 'SORT_BY_INIT_PRIORITY(%s)'
  98. elif self.sort == ('name', 'alignment'):
  99. pattern = 'SORT_BY_NAME(SORT_BY_ALIGNMENT(%s))'
  100. elif self.sort == ('alignment', 'name'):
  101. pattern = 'SORT_BY_ALIGNMENT(SORT_BY_NAME(%s))'
  102. elif self.sort == ('name', 'name'):
  103. pattern = 'SORT_BY_NAME(SORT_BY_NAME(%s))'
  104. elif self.sort == ('alignment', 'alignment'):
  105. pattern = 'SORT_BY_ALIGNMENT(SORT_BY_ALIGNMENT(%s))'
  106. else:
  107. raise Exception('Invalid sort arguments')
  108. section_strings = [(pattern % s) for s in section_strings]
  109. sections_string = '(%s)' % ' '.join(section_strings)
  110. if self.entity.specificity == Entity.Specificity.NONE:
  111. entry = '*%s' % (sections_string)
  112. elif self.entity.specificity == Entity.Specificity.ARCHIVE:
  113. entry = '*%s:%s' % (self.entity.archive, sections_string)
  114. else:
  115. entry = '*%s:%s.*%s' % (self.entity.archive, self.entity.obj, sections_string)
  116. if self.keep:
  117. res = 'KEEP(%s)' % entry
  118. else:
  119. res = entry
  120. return res
  121. def __eq__(self, other):
  122. return (isinstance(other, InputSectionDesc) and
  123. self.entity == other.entity and
  124. self.sections == other.sections and
  125. self.exclusions == other.exclusions and
  126. self.keep == other.keep and
  127. self.sort == other.sort)