emdbg.analyze.size
1# Copyright (c) 2024, Alexander Lerach 2# Copyright (c) 2024, Auterion AG 3# SPDX-License-Identifier: BSD-3-Clause 4 5from dataclasses import dataclass 6from enum import Enum 7from pathlib import Path 8from shutil import which 9import argparse 10import logging 11import re 12import subprocess 13 14import rich 15from rich.console import Console 16from rich.table import Table 17 18_LOGGER = logging.getLogger(__name__) 19_BLOATY_CMD = "bloaty" 20 21 22# ----------------------------------------------------------------------------- 23def _rel_file_name(file_path: Path) -> str: 24 """Return the filename relative to the CWD.""" 25 try: return str(Path(file_path).relative_to(Path().cwd())) 26 except ValueError: return str(Path(file_path)) 27 28 29# ----------------------------------------------------------------------------- 30def _remove_all_spaces(s: str) -> str: 31 """Removes all spaces from the given string.""" 32 return ''.join(s.split()) 33 34 35# ----------------------------------------------------------------------------- 36def is_bloaty_installed() -> bool: 37 """Checks if bloaty is installed and contained in PATH.""" 38 return which(_BLOATY_CMD) is not None 39 40 41# ----------------------------------------------------------------------------- 42class SectionType(Enum): 43 """ 44 The `SectionType` describes what kind of type a linker section is. 45 """ 46 text = 0, 47 rodata = 1, 48 bss = 2, 49 data = 3, 50 debug = 4, 51 unknown = 5 52 53 54# ----------------------------------------------------------------------------- 55@dataclass 56class Section: 57 """ 58 The class `Section` represents a linker section. 59 """ 60 name: str 61 """name of the linker section.""" 62 section_type: SectionType 63 """type of the linker section.""" 64 vm_size: int 65 """VM size that the linker section uses""" 66 file_size: int 67 """file size that the linker section uses""" 68 69 70# ----------------------------------------------------------------------------- 71@dataclass 72class AnalysisResult: 73 """ 74 The class `AnalysisResult` represents the result of an inline analysis performed using `SectionAnalyzer`. 75 """ 76 file_path: Path 77 """path of the file that was analyzed.""" 78 sections: list[Section] 79 """all linker sections that were found in the analyzed file and passed the given filters.""" 80 total_vm_size: int 81 """overall VM size that is used by all sections in the analyzed file.""" 82 total_file_size: int 83 """overall file size that is used by all sections in the analyzed file.""" 84 85 def print(self, console: Console, overall_vm_size: int, overall_file_size: int): 86 """ 87 Prints the analyzed file with its linker sections in an easy-to-read format. 88 89 :param console: console to print the output to. 90 :param overall_vm_size: overall VM size that is used by all sections of all analyzed files. 91 :param overall_file_size: overall file size that is used by all sections of all analyzed files. 92 """ 93 console.print(( 94 f"{_rel_file_name(self.file_path)} -- Total VM Size: {self.total_vm_size}" 95 f" ({(100 if overall_vm_size == 0 else (self.total_vm_size / overall_vm_size * 100)):.2f}%)" 96 f" -- Total File Size: {self.total_file_size}" 97 f" ({(100 if overall_file_size == 0 else (self.total_file_size / overall_file_size * 100)):.2f}%)" 98 )) 99 100 table = Table(box=rich.box.MINIMAL_DOUBLE_HEAD) 101 table.add_column("Section") 102 table.add_column("Type") 103 table.add_column("VM size") 104 table.add_column("File size") 105 table.add_column("% (VM size)") 106 table.add_column("% (File size)") 107 108 for section in self.sections: 109 table.add_row(section.name, str(section.section_type.name), str(section.vm_size), str(section.file_size), 110 "{:.2f}".format(100 if self.total_vm_size == 0 else section.vm_size / self.total_vm_size * 100), 111 "{:.2f}".format(100 if self.total_file_size == 0 else section.file_size / self.total_file_size * 100)) 112 113 console.print(table) 114 115 def to_csv_lines(self) -> str: 116 """ 117 Prints the analyzed file with its linker sections into the CSV format. This allows for analysis in another tool. 118 """ 119 out = "" 120 121 for section in self.sections: 122 out = out + f"{_rel_file_name(self.file_path)},{section.name},{section.section_type.name},{section.vm_size},{section.file_size}\n" 123 return out 124 125 126# ----------------------------------------------------------------------------- 127class SectionAnalyzer: 128 """ 129 The `SectionAnalyzer` extracts information about linker sections using bloaty. 130 131 :param map_file_content: The contents of the map file. If `None` is passed, the output may contain sections that are removed by the linker. 132 :param all_vm: Tells whether to include sections with a VM size of 0. 133 :param section_filter: Regex that will be used as a filter on section names. `None` in case of no filter. 134 :param type_filter: List of section types that shall be considered. Empty in case of no filters. 135 """ 136 def __init__(self, map_file_content: str | None, all_vm: bool, section_filter: str | None, type_filter: list[str]): 137 self._map_file_content = map_file_content 138 self._all_vm = all_vm 139 self._section_filter = section_filter 140 self._type_filter = type_filter 141 142 def get_sections(self, file_path: Path) -> AnalysisResult | None: 143 """ 144 Analyzes the given file using bloaty and returns all identified `Section`. In case of any errors, `None` will be returned. 145 The sections will only be added to the output, if they pass the given filters. 146 If a map file is provided all sections that are removed by the linker will be removed from the output. 147 148 :param file_path: the file to analyze. 149 150 :return: on success, all identified `Section`. Otherwise, `None` will be returned. 151 """ 152 sections = [] 153 total_vm_size = 0 154 total_file_size = 0 155 bloaty_output = self.get_bloaty_output(file_path) 156 157 if bloaty_output: 158 for line in bloaty_output.splitlines()[1:]: 159 line_split = line.split(",") 160 161 if len(line_split) == 3 and line_split[1].isdigit() and line_split[2].isdigit(): 162 section_type = self.get_section_type(line_split[0]) 163 section = Section(line_split[0], section_type, int(line_split[1]), int(line_split[2])) 164 165 if section.vm_size > 0 or self._all_vm: 166 if self.check_section_map_file(section) and self.check_section_filter(section) and self.check_section_type_filter(section): 167 sections.append(section) 168 total_vm_size = total_vm_size + section.vm_size 169 total_file_size = total_file_size + section.file_size 170 else: 171 _LOGGER.error(f"bloaty output contains invalid line: {line}") 172 return None 173 return AnalysisResult(file_path, sections, total_vm_size, total_file_size) 174 else: 175 return None 176 177 def get_bloaty_output(self, file_path: Path) -> str | None: 178 """ 179 Runs bloaty on the given file and collects its stdout if bloaty returns successfully. If it reports an error, `None` will be returned. 180 The following args are passed to bloaty: 181 - `-s vm`: Sort the output by VM size. 182 - `-n 0`: Output all sections. 183 - `--csv`: Output as CSV to stdout, which is easier to parse than the normal output. 184 185 :param file_path: the file to analyze using bloaty. 186 187 :return: on success, the bloaty stdout is returned. Otherwise, `None` will be returned. 188 """ 189 res = subprocess.run([_BLOATY_CMD, "-s", "vm", "-n", "0", "--csv", f"{file_path.as_posix()}"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 190 191 if res.returncode == 0: 192 return res.stdout.decode() 193 else: 194 _LOGGER.error(f"bloaty returned with: {res.returncode}. stdout: {res.stdout.decode()}. stderr: {res.stderr.decode()}") 195 return None 196 197 def get_section_type(self, section_name: str) -> SectionType: 198 """Gets the type of the section based on its name. If this is not possible the type will be set to `unkown`.""" 199 for type in SectionType: 200 if section_name.startswith(f".{type.name}"): 201 return type 202 return SectionType.unknown 203 204 def check_section_map_file(self, section: Section) -> bool: 205 """Check if the section is contained in the map file (and thus was not removed by the linker).""" 206 return self._map_file_content is None or section.name in self._map_file_content 207 208 def check_section_filter(self, section: Section) -> bool: 209 """Check if the section name matches the user given regex. If no regex is given, always returns True.""" 210 return self._section_filter is None or re.compile(self._section_filter).match(section.name) 211 212 def check_section_type_filter(self, section: Section) -> bool: 213 """Check if the section type matches the user given type filter. If no filter is given, always returns True.""" 214 return len(self._type_filter) == 0 or section.section_type.name in self._type_filter 215 216 217# ----------------------------------------------------------------------------- 218if __name__ == "__main__": 219 parser = argparse.ArgumentParser(description="Section size analyzer.") 220 parser.add_argument( 221 "--build-dir", 222 help="Path to the build directory. If not given, the current working directory will be used instead." 223 ) 224 parser.add_argument( 225 "--map-file", 226 help="Path to the map file. It is used to remove sections that got removed by the linker from the analysis results." 227 ) 228 parser.add_argument( 229 "--type-filter", 230 help="Comma separated list of section types to filter for. For example '-t rodata,text' would only show rodata and text sections." 231 ) 232 parser.add_argument( 233 "--section-filter", 234 help="Regex that will be applied to section names. Only the ones that match the regex will be considered." 235 ) 236 parser.add_argument( 237 "--csv", 238 action="store_true", 239 default=False, 240 help="Write output to a CSV file instead of stdout." 241 ) 242 parser.add_argument( 243 "--all-vm", 244 action="store_true", 245 default=False, 246 help="Also include sections with a VM size of 0." 247 ) 248 249 args = parser.parse_args() 250 251 build_dir = Path().cwd() 252 map_file_content = None 253 type_filter = [] 254 255 if not is_bloaty_installed(): 256 _LOGGER.error("bloaty is not installed. Please install it to use this tool.") 257 exit(1) 258 259 if args.build_dir: 260 build_dir = Path(args.build_dir) 261 262 if not build_dir.exists(): 263 _LOGGER.error(f"Given build directory: {build_dir} does not exist.") 264 exit(1) 265 266 if args.map_file: 267 map_file_path = Path(args.map_file) 268 269 if not map_file_path.exists(): 270 _LOGGER.error(f"Given map file: {map_file_path} does not exist.") 271 exit(1) 272 with open(args.map_file, "r") as f: 273 map_file_content = f.read() 274 275 if args.type_filter: 276 type_filter = _remove_all_spaces(args.type_filter).split(",") 277 278 if args.section_filter: 279 try: 280 re.compile(args.section_filter) 281 except re.error: 282 _LOGGER.error(f"Given regex: {args.section_filter} is not valid.") 283 exit(1) 284 285 console = Console() 286 section_analyzer = SectionAnalyzer(map_file_content, args.all_vm, args.section_filter, type_filter) 287 288 res = [] 289 overall_vm_size = 0 290 overall_file_size = 0 291 292 for file_path in build_dir.rglob("*.a"): 293 analysis_result = section_analyzer.get_sections(file_path) 294 295 if analysis_result: 296 res.append(analysis_result) 297 overall_vm_size = overall_vm_size + analysis_result.total_vm_size 298 overall_file_size = overall_file_size + analysis_result.total_file_size 299 300 res.sort(key=lambda x: x.total_vm_size, reverse=True) 301 302 if args.csv: 303 with open("output.csv", "w") as f: 304 f.write("file_path,section,type,vm_size,file_size\n") 305 306 for analysis_result in res: 307 if analysis_result.total_vm_size > 0 or args.all_vm: 308 f.write(analysis_result.to_csv_lines()) 309 else: 310 for analysis_result in res: 311 if analysis_result.total_vm_size > 0 or args.all_vm: 312 analysis_result.print(console, overall_vm_size, overall_file_size) 313 console.print("")
37def is_bloaty_installed() -> bool: 38 """Checks if bloaty is installed and contained in PATH.""" 39 return which(_BLOATY_CMD) is not None
Checks if bloaty is installed and contained in PATH.
43class SectionType(Enum): 44 """ 45 The `SectionType` describes what kind of type a linker section is. 46 """ 47 text = 0, 48 rodata = 1, 49 bss = 2, 50 data = 3, 51 debug = 4, 52 unknown = 5
The SectionType
describes what kind of type a linker section is.
56@dataclass 57class Section: 58 """ 59 The class `Section` represents a linker section. 60 """ 61 name: str 62 """name of the linker section.""" 63 section_type: SectionType 64 """type of the linker section.""" 65 vm_size: int 66 """VM size that the linker section uses""" 67 file_size: int 68 """file size that the linker section uses"""
The class Section
represents a linker section.
72@dataclass 73class AnalysisResult: 74 """ 75 The class `AnalysisResult` represents the result of an inline analysis performed using `SectionAnalyzer`. 76 """ 77 file_path: Path 78 """path of the file that was analyzed.""" 79 sections: list[Section] 80 """all linker sections that were found in the analyzed file and passed the given filters.""" 81 total_vm_size: int 82 """overall VM size that is used by all sections in the analyzed file.""" 83 total_file_size: int 84 """overall file size that is used by all sections in the analyzed file.""" 85 86 def print(self, console: Console, overall_vm_size: int, overall_file_size: int): 87 """ 88 Prints the analyzed file with its linker sections in an easy-to-read format. 89 90 :param console: console to print the output to. 91 :param overall_vm_size: overall VM size that is used by all sections of all analyzed files. 92 :param overall_file_size: overall file size that is used by all sections of all analyzed files. 93 """ 94 console.print(( 95 f"{_rel_file_name(self.file_path)} -- Total VM Size: {self.total_vm_size}" 96 f" ({(100 if overall_vm_size == 0 else (self.total_vm_size / overall_vm_size * 100)):.2f}%)" 97 f" -- Total File Size: {self.total_file_size}" 98 f" ({(100 if overall_file_size == 0 else (self.total_file_size / overall_file_size * 100)):.2f}%)" 99 )) 100 101 table = Table(box=rich.box.MINIMAL_DOUBLE_HEAD) 102 table.add_column("Section") 103 table.add_column("Type") 104 table.add_column("VM size") 105 table.add_column("File size") 106 table.add_column("% (VM size)") 107 table.add_column("% (File size)") 108 109 for section in self.sections: 110 table.add_row(section.name, str(section.section_type.name), str(section.vm_size), str(section.file_size), 111 "{:.2f}".format(100 if self.total_vm_size == 0 else section.vm_size / self.total_vm_size * 100), 112 "{:.2f}".format(100 if self.total_file_size == 0 else section.file_size / self.total_file_size * 100)) 113 114 console.print(table) 115 116 def to_csv_lines(self) -> str: 117 """ 118 Prints the analyzed file with its linker sections into the CSV format. This allows for analysis in another tool. 119 """ 120 out = "" 121 122 for section in self.sections: 123 out = out + f"{_rel_file_name(self.file_path)},{section.name},{section.section_type.name},{section.vm_size},{section.file_size}\n" 124 return out
The class AnalysisResult
represents the result of an inline analysis performed using SectionAnalyzer
.
all linker sections that were found in the analyzed file and passed the given filters.
86 def print(self, console: Console, overall_vm_size: int, overall_file_size: int): 87 """ 88 Prints the analyzed file with its linker sections in an easy-to-read format. 89 90 :param console: console to print the output to. 91 :param overall_vm_size: overall VM size that is used by all sections of all analyzed files. 92 :param overall_file_size: overall file size that is used by all sections of all analyzed files. 93 """ 94 console.print(( 95 f"{_rel_file_name(self.file_path)} -- Total VM Size: {self.total_vm_size}" 96 f" ({(100 if overall_vm_size == 0 else (self.total_vm_size / overall_vm_size * 100)):.2f}%)" 97 f" -- Total File Size: {self.total_file_size}" 98 f" ({(100 if overall_file_size == 0 else (self.total_file_size / overall_file_size * 100)):.2f}%)" 99 )) 100 101 table = Table(box=rich.box.MINIMAL_DOUBLE_HEAD) 102 table.add_column("Section") 103 table.add_column("Type") 104 table.add_column("VM size") 105 table.add_column("File size") 106 table.add_column("% (VM size)") 107 table.add_column("% (File size)") 108 109 for section in self.sections: 110 table.add_row(section.name, str(section.section_type.name), str(section.vm_size), str(section.file_size), 111 "{:.2f}".format(100 if self.total_vm_size == 0 else section.vm_size / self.total_vm_size * 100), 112 "{:.2f}".format(100 if self.total_file_size == 0 else section.file_size / self.total_file_size * 100)) 113 114 console.print(table)
Prints the analyzed file with its linker sections in an easy-to-read format.
Parameters
- console: console to print the output to.
- overall_vm_size: overall VM size that is used by all sections of all analyzed files.
- overall_file_size: overall file size that is used by all sections of all analyzed files.
116 def to_csv_lines(self) -> str: 117 """ 118 Prints the analyzed file with its linker sections into the CSV format. This allows for analysis in another tool. 119 """ 120 out = "" 121 122 for section in self.sections: 123 out = out + f"{_rel_file_name(self.file_path)},{section.name},{section.section_type.name},{section.vm_size},{section.file_size}\n" 124 return out
Prints the analyzed file with its linker sections into the CSV format. This allows for analysis in another tool.
128class SectionAnalyzer: 129 """ 130 The `SectionAnalyzer` extracts information about linker sections using bloaty. 131 132 :param map_file_content: The contents of the map file. If `None` is passed, the output may contain sections that are removed by the linker. 133 :param all_vm: Tells whether to include sections with a VM size of 0. 134 :param section_filter: Regex that will be used as a filter on section names. `None` in case of no filter. 135 :param type_filter: List of section types that shall be considered. Empty in case of no filters. 136 """ 137 def __init__(self, map_file_content: str | None, all_vm: bool, section_filter: str | None, type_filter: list[str]): 138 self._map_file_content = map_file_content 139 self._all_vm = all_vm 140 self._section_filter = section_filter 141 self._type_filter = type_filter 142 143 def get_sections(self, file_path: Path) -> AnalysisResult | None: 144 """ 145 Analyzes the given file using bloaty and returns all identified `Section`. In case of any errors, `None` will be returned. 146 The sections will only be added to the output, if they pass the given filters. 147 If a map file is provided all sections that are removed by the linker will be removed from the output. 148 149 :param file_path: the file to analyze. 150 151 :return: on success, all identified `Section`. Otherwise, `None` will be returned. 152 """ 153 sections = [] 154 total_vm_size = 0 155 total_file_size = 0 156 bloaty_output = self.get_bloaty_output(file_path) 157 158 if bloaty_output: 159 for line in bloaty_output.splitlines()[1:]: 160 line_split = line.split(",") 161 162 if len(line_split) == 3 and line_split[1].isdigit() and line_split[2].isdigit(): 163 section_type = self.get_section_type(line_split[0]) 164 section = Section(line_split[0], section_type, int(line_split[1]), int(line_split[2])) 165 166 if section.vm_size > 0 or self._all_vm: 167 if self.check_section_map_file(section) and self.check_section_filter(section) and self.check_section_type_filter(section): 168 sections.append(section) 169 total_vm_size = total_vm_size + section.vm_size 170 total_file_size = total_file_size + section.file_size 171 else: 172 _LOGGER.error(f"bloaty output contains invalid line: {line}") 173 return None 174 return AnalysisResult(file_path, sections, total_vm_size, total_file_size) 175 else: 176 return None 177 178 def get_bloaty_output(self, file_path: Path) -> str | None: 179 """ 180 Runs bloaty on the given file and collects its stdout if bloaty returns successfully. If it reports an error, `None` will be returned. 181 The following args are passed to bloaty: 182 - `-s vm`: Sort the output by VM size. 183 - `-n 0`: Output all sections. 184 - `--csv`: Output as CSV to stdout, which is easier to parse than the normal output. 185 186 :param file_path: the file to analyze using bloaty. 187 188 :return: on success, the bloaty stdout is returned. Otherwise, `None` will be returned. 189 """ 190 res = subprocess.run([_BLOATY_CMD, "-s", "vm", "-n", "0", "--csv", f"{file_path.as_posix()}"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 191 192 if res.returncode == 0: 193 return res.stdout.decode() 194 else: 195 _LOGGER.error(f"bloaty returned with: {res.returncode}. stdout: {res.stdout.decode()}. stderr: {res.stderr.decode()}") 196 return None 197 198 def get_section_type(self, section_name: str) -> SectionType: 199 """Gets the type of the section based on its name. If this is not possible the type will be set to `unkown`.""" 200 for type in SectionType: 201 if section_name.startswith(f".{type.name}"): 202 return type 203 return SectionType.unknown 204 205 def check_section_map_file(self, section: Section) -> bool: 206 """Check if the section is contained in the map file (and thus was not removed by the linker).""" 207 return self._map_file_content is None or section.name in self._map_file_content 208 209 def check_section_filter(self, section: Section) -> bool: 210 """Check if the section name matches the user given regex. If no regex is given, always returns True.""" 211 return self._section_filter is None or re.compile(self._section_filter).match(section.name) 212 213 def check_section_type_filter(self, section: Section) -> bool: 214 """Check if the section type matches the user given type filter. If no filter is given, always returns True.""" 215 return len(self._type_filter) == 0 or section.section_type.name in self._type_filter
The SectionAnalyzer
extracts information about linker sections using bloaty.
Parameters
- map_file_content: The contents of the map file. If
None
is passed, the output may contain sections that are removed by the linker. - all_vm: Tells whether to include sections with a VM size of 0.
- section_filter: Regex that will be used as a filter on section names.
None
in case of no filter. - type_filter: List of section types that shall be considered. Empty in case of no filters.
143 def get_sections(self, file_path: Path) -> AnalysisResult | None: 144 """ 145 Analyzes the given file using bloaty and returns all identified `Section`. In case of any errors, `None` will be returned. 146 The sections will only be added to the output, if they pass the given filters. 147 If a map file is provided all sections that are removed by the linker will be removed from the output. 148 149 :param file_path: the file to analyze. 150 151 :return: on success, all identified `Section`. Otherwise, `None` will be returned. 152 """ 153 sections = [] 154 total_vm_size = 0 155 total_file_size = 0 156 bloaty_output = self.get_bloaty_output(file_path) 157 158 if bloaty_output: 159 for line in bloaty_output.splitlines()[1:]: 160 line_split = line.split(",") 161 162 if len(line_split) == 3 and line_split[1].isdigit() and line_split[2].isdigit(): 163 section_type = self.get_section_type(line_split[0]) 164 section = Section(line_split[0], section_type, int(line_split[1]), int(line_split[2])) 165 166 if section.vm_size > 0 or self._all_vm: 167 if self.check_section_map_file(section) and self.check_section_filter(section) and self.check_section_type_filter(section): 168 sections.append(section) 169 total_vm_size = total_vm_size + section.vm_size 170 total_file_size = total_file_size + section.file_size 171 else: 172 _LOGGER.error(f"bloaty output contains invalid line: {line}") 173 return None 174 return AnalysisResult(file_path, sections, total_vm_size, total_file_size) 175 else: 176 return None
Analyzes the given file using bloaty and returns all identified Section
. In case of any errors, None
will be returned.
The sections will only be added to the output, if they pass the given filters.
If a map file is provided all sections that are removed by the linker will be removed from the output.
Parameters
- file_path: the file to analyze.
Returns
on success, all identified
Section
. Otherwise,None
will be returned.
178 def get_bloaty_output(self, file_path: Path) -> str | None: 179 """ 180 Runs bloaty on the given file and collects its stdout if bloaty returns successfully. If it reports an error, `None` will be returned. 181 The following args are passed to bloaty: 182 - `-s vm`: Sort the output by VM size. 183 - `-n 0`: Output all sections. 184 - `--csv`: Output as CSV to stdout, which is easier to parse than the normal output. 185 186 :param file_path: the file to analyze using bloaty. 187 188 :return: on success, the bloaty stdout is returned. Otherwise, `None` will be returned. 189 """ 190 res = subprocess.run([_BLOATY_CMD, "-s", "vm", "-n", "0", "--csv", f"{file_path.as_posix()}"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) 191 192 if res.returncode == 0: 193 return res.stdout.decode() 194 else: 195 _LOGGER.error(f"bloaty returned with: {res.returncode}. stdout: {res.stdout.decode()}. stderr: {res.stderr.decode()}") 196 return None
Runs bloaty on the given file and collects its stdout if bloaty returns successfully. If it reports an error, None
will be returned.
The following args are passed to bloaty:
-s vm
: Sort the output by VM size.-n 0
: Output all sections.--csv
: Output as CSV to stdout, which is easier to parse than the normal output.
Parameters
- file_path: the file to analyze using bloaty.
Returns
on success, the bloaty stdout is returned. Otherwise,
None
will be returned.
198 def get_section_type(self, section_name: str) -> SectionType: 199 """Gets the type of the section based on its name. If this is not possible the type will be set to `unkown`.""" 200 for type in SectionType: 201 if section_name.startswith(f".{type.name}"): 202 return type 203 return SectionType.unknown
Gets the type of the section based on its name. If this is not possible the type will be set to unkown
.
205 def check_section_map_file(self, section: Section) -> bool: 206 """Check if the section is contained in the map file (and thus was not removed by the linker).""" 207 return self._map_file_content is None or section.name in self._map_file_content
Check if the section is contained in the map file (and thus was not removed by the linker).
209 def check_section_filter(self, section: Section) -> bool: 210 """Check if the section name matches the user given regex. If no regex is given, always returns True.""" 211 return self._section_filter is None or re.compile(self._section_filter).match(section.name)
Check if the section name matches the user given regex. If no regex is given, always returns True.
213 def check_section_type_filter(self, section: Section) -> bool: 214 """Check if the section type matches the user given type filter. If no filter is given, always returns True.""" 215 return len(self._type_filter) == 0 or section.section_type.name in self._type_filter
Check if the section type matches the user given type filter. If no filter is given, always returns True.