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 17from entity import Entity 18 19# Contains classes for output section commands referred to in 20# https://www.acrc.bris.ac.uk/acrc/RedHat/rhel-ld-en-4/sections.html#OUTPUT-SECTION-DESCRIPTION. 21 22 23class AlignAtAddress(): 24 """ 25 Outputs assignment of builtin function ALIGN to current 26 position: 27 28 . = ALIGN(<alignment>) 29 30 Mapping fragment flag ALIGN causes this output section 31 command to be emitted. 32 """ 33 34 def __init__(self, alignment): 35 self.alignment = alignment 36 37 def __str__(self): 38 return ('. = ALIGN(%d);' % self.alignment) 39 40 def __eq__(self, other): 41 return (isinstance(other, AlignAtAddress) and 42 self.alignment == other.alignment) 43 44 45class SymbolAtAddress(): 46 """ 47 Outputs assignment of builtin function ABSOLUTE to a symbol 48 for current position: 49 50 <symbol> = ABSOLUTE(.) 51 52 Mapping fragment flag SURROUND causes this 53 output section command to be emitted before and after 54 an InputSectionDesc. 55 """ 56 57 def __init__(self, symbol): 58 self.symbol = symbol 59 60 def __str__(self): 61 return ('%s = ABSOLUTE(.);' % self.symbol) 62 63 def __eq__(self, other): 64 return (isinstance(other, SymbolAtAddress) and 65 self.symbol == other.symbol) 66 67 68class InputSectionDesc(): 69 """ 70 Outputs an input section description as described in 71 https://www.acrc.bris.ac.uk/acrc/RedHat/rhel-ld-en-4/sections.html#INPUT-SECTION. 72 73 These commands are emmited from mapping fragment entries, specifically attaching 74 a scheme onto an entity. Mapping fragment flags KEEP, SORT will also affect 75 the emitted input section description. 76 """ 77 78 def __init__(self, entity, sections, exclusions=None, keep=False, sort=None): 79 assert(entity.specificity != Entity.Specificity.SYMBOL) 80 81 self.entity = entity 82 self.sections = set(sections) 83 84 self.exclusions = set() 85 86 if exclusions: 87 assert(not [e for e in exclusions if e.specificity == Entity.Specificity.SYMBOL or 88 e.specificity == Entity.Specificity.NONE]) 89 self.exclusions = set(exclusions) 90 else: 91 self.exclusions = set() 92 93 self.keep = keep 94 self.sort = sort 95 96 def __str__(self): 97 sections_string = '( )' 98 99 if self.sections: 100 exclusion_strings = [] 101 102 for exc in sorted(self.exclusions): 103 if exc.specificity == Entity.Specificity.ARCHIVE: 104 exc_string = '*%s' % (exc.archive) 105 else: 106 exc_string = '*%s:%s.*' % (exc.archive, exc.obj) 107 108 exclusion_strings.append(exc_string) 109 110 section_strings = [] 111 112 if exclusion_strings: 113 exclusion_string = 'EXCLUDE_FILE(%s)' % ' '.join(exclusion_strings) 114 115 for section in sorted(self.sections): 116 section_strings.append('%s %s' % (exclusion_string, section)) 117 else: 118 for section in sorted(self.sections): 119 section_strings.append(section) 120 121 if self.sort: 122 if self.sort == (None, None): 123 pattern = 'SORT(%s)' 124 elif self.sort == ('name', None): 125 pattern = 'SORT_BY_NAME(%s)' 126 elif self.sort == ('alignment', None): 127 pattern = 'SORT_BY_ALIGNMENT(%s)' 128 elif self.sort == ('init_priority', None): 129 pattern = 'SORT_BY_INIT_PRIORITY(%s)' 130 elif self.sort == ('name', 'alignment'): 131 pattern = 'SORT_BY_NAME(SORT_BY_ALIGNMENT(%s))' 132 elif self.sort == ('alignment', 'name'): 133 pattern = 'SORT_BY_ALIGNMENT(SORT_BY_NAME(%s))' 134 elif self.sort == ('name', 'name'): 135 pattern = 'SORT_BY_NAME(SORT_BY_NAME(%s))' 136 elif self.sort == ('alignment', 'alignment'): 137 pattern = 'SORT_BY_ALIGNMENT(SORT_BY_ALIGNMENT(%s))' 138 else: 139 raise Exception('Invalid sort arguments') 140 141 section_strings = [(pattern % s) for s in section_strings] 142 143 sections_string = '(%s)' % ' '.join(section_strings) 144 145 if self.entity.specificity == Entity.Specificity.NONE: 146 entry = '*%s' % (sections_string) 147 elif self.entity.specificity == Entity.Specificity.ARCHIVE: 148 entry = '*%s:%s' % (self.entity.archive, sections_string) 149 else: 150 entry = '*%s:%s.*%s' % (self.entity.archive, self.entity.obj, sections_string) 151 152 if self.keep: 153 res = 'KEEP(%s)' % entry 154 else: 155 res = entry 156 157 return res 158 159 def __eq__(self, other): 160 return (isinstance(other, InputSectionDesc) and 161 self.entity == other.entity and 162 self.sections == other.sections and 163 self.exclusions == other.exclusions and 164 self.keep == other.keep and 165 self.sort == other.sort) 166