diff --git a/cocas/assembler/assembler.py b/cocas/assembler/assembler.py index 22da7e9c..90ea3e79 100644 --- a/cocas/assembler/assembler.py +++ b/cocas/assembler/assembler.py @@ -99,7 +99,8 @@ def assemble_files(target: str, for j in lib.code_locations.values(): if j.file == fp: j.file = dip - else: - j.file = get_debug_info_path(Path(j.file), debug, relative_path, realpath) + elif j.file is not None: + p = get_debug_info_path(Path(j.file), debug, relative_path, realpath) + j.file = str(p) if p is not None else None objects.append((filepath, obj)) return objects diff --git a/cocas/assembler/ast_builder.py b/cocas/assembler/ast_builder.py index aea43ea6..eaab08ae 100644 --- a/cocas/assembler/ast_builder.py +++ b/cocas/assembler/ast_builder.py @@ -1,10 +1,13 @@ import codecs import warnings from base64 import b64decode +from collections.abc import Mapping, MutableSequence from pathlib import Path +from typing import cast from antlr4 import CommonTokenStream, InputStream +from cocas.assembler.constants import DBG_LOC_INST, DBG_SOURCE_INST from cocas.object_module import CodeLocation from .ast_nodes import ( @@ -22,6 +25,7 @@ RegisterNode, RelocatableExpressionNode, RelocatableSectionNode, + SectionNode, TemplateSectionNode, UntilLoopNode, WhileLoopNode, @@ -32,7 +36,7 @@ # noinspection PyPep8Naming class BuildAstVisitor(AsmParserVisitor): - allowed_top_instructions = [] + allowed_top_instructions = [DBG_SOURCE_INST] def __init__(self, filepath: str): super().__init__() @@ -43,8 +47,11 @@ def __init__(self, filepath: str): self.in_macro = False self.current_macro_file = "" self.current_macro_line = 0 + self.generated: bool = False def _ctx_location(self, ctx) -> CodeLocation: + if self.generated: + return CodeLocation() if self.in_macro: return CodeLocation(self.current_macro_file, self.current_macro_line) return CodeLocation(self.source_path, ctx.start.line - self.line_offset) @@ -61,7 +68,9 @@ def visitProgram(self, ctx: AsmParser.ProgramContext) -> ProgramNode: elif isinstance(child, AsmParser.Line_markContext): self.visitLine_mark(child) elif isinstance(child, AsmParser.Top_lineContext): - ret.shared_externals, ret.top_instructions = self.visitTop_line(child) + shared, top = self.visitTop_line(child) + ret.shared_externals.extend(shared) + ret.top_instructions.extend(top) return ret def visitTop_line(self, ctx: AsmParser.Top_lineContext) -> tuple[list[LabelNode], list[InstructionNode]]: @@ -305,6 +314,7 @@ def visitInstructionLine(self, ctx: AsmParser.InstructionLineContext) -> list[No if ctx.labels_declaration() is not None: ret += self.visitLabels_declaration(ctx.labels_declaration()) op = ctx.instruction().getText() + self.generated |= op == DBG_SOURCE_INST args = self.visitArguments(ctx.arguments()) if ctx.arguments() is not None else [] ret.append(InstructionNode(op, args)) return ret @@ -313,7 +323,72 @@ def visitArguments(self, ctx: AsmParser.ArgumentsContext): return [self.visitArgument(i) for i in ctx.children if isinstance(i, AsmParser.ArgumentContext)] -def build_ast(input_stream: InputStream, filepath: Path): +Ren = RelocatableExpressionNode + + +def resolve_debug_locs(files: Mapping[int, str], sections: MutableSequence[SectionNode]) -> None: + for section in sections: + lines_iter = enumerate(iter(section.lines)) + loc_insts: list[int] = [] + + for index, line_node in lines_iter: + if not isinstance(line_node, InstructionNode) or line_node.mnemonic != DBG_LOC_INST: + continue + loc_insts.append(index) + match line_node.arguments: + case [Ren(_, _, _, file), Ren(_, _, _, line), Ren(_, _, _, column)]: + if (path := files.get(file)) is None: + raise AssemblerException(AssemblerExceptionTag.ASM, line_node.location.file, + line_node.location.column, + f"{DBG_LOC_INST} refers to file with index {file}; where is no {DBG_SOURCE_INST} with such index") + current_loc = CodeLocation(path, line, column) + case _: + raise AssemblerException(AssemblerExceptionTag.ASM, line_node.location.file, + line_node.location.column, + f"{DBG_LOC_INST} expects a number and a string, while {line_node.arguments} provided") + + _, next_line_node = next(lines_iter, (None, None)) + if next_line_node is None: + raise AssemblerException(AssemblerExceptionTag.ASM, line_node.location.file, line_node.location.column, + f"expected an instruction line after {DBG_LOC_INST}, while it's missing") + if not isinstance(next_line_node, InstructionNode): + raise AssemblerException(AssemblerExceptionTag.ASM, line_node.location.file, line_node.location.column, + f"expected an instruction line after {DBG_LOC_INST}, while {type(next_line_node)} has been found") + if next_line_node.mnemonic == DBG_LOC_INST: + raise AssemblerException(AssemblerExceptionTag.ASM, line_node.location.file, line_node.location.column, + f"there are two consecutive {DBG_LOC_INST} instructions; there is no point to do that") + next_line_node.location = current_loc + + for index in reversed(loc_insts): + _ = section.lines.pop(index) + + +def resolve_debug_pseudos(pn: ProgramNode) -> None: + files: dict[int, str] = {} + source_insts: list[int] = [] + + for index, ti in enumerate(pn.top_instructions): + if ti.mnemonic != DBG_SOURCE_INST: + continue + match ti.arguments: + case [Ren(_, _, _, index), str() as path]: + if index in files: + raise AssemblerException(AssemblerExceptionTag.ASM, ti.location.file, ti.location.column, + f"duplicate {DBG_SOURCE_INST} for index {index}") + files[index] = path + case _: + raise AssemblerException(AssemblerExceptionTag.ASM, ti.location.file, ti.location.column, + f"{DBG_SOURCE_INST} expects a number and a string, while {ti.arguments} provided") + source_insts.append(index) + + for index in reversed(source_insts): + _ = pn.top_instructions.pop(index) + + resolve_debug_locs(files, cast(list[SectionNode], pn.absolute_sections)) + resolve_debug_locs(files, cast(list[SectionNode], pn.relocatable_sections)) + + +def build_ast(input_stream: InputStream, filepath: Path) -> ProgramNode: str_path = filepath.absolute().as_posix() lexer = AsmLexer(input_stream) lexer.removeErrorListeners() @@ -326,4 +401,8 @@ def build_ast(input_stream: InputStream, filepath: Path): cst = parser.program() bav = BuildAstVisitor(str_path) result = bav.visit(cst) + if not isinstance(result, ProgramNode): + raise AssemblerException(AssemblerExceptionTag.ASM, str_path, 0, + "failed to build a program AST from provided code") + resolve_debug_pseudos(result) return result diff --git a/cocas/assembler/ast_nodes.py b/cocas/assembler/ast_nodes.py index 7abb69c7..e6e4fbc5 100644 --- a/cocas/assembler/ast_nodes.py +++ b/cocas/assembler/ast_nodes.py @@ -21,14 +21,12 @@ class LabelNode(Node): @dataclass class LocatableNode(Node): - def __post_init__(self): - self.location: CodeLocation = CodeLocation() + location: CodeLocation = field(default_factory=CodeLocation, init=False, compare=False) @dataclass class ExportLocationNode(LocatableNode): - def __post_init__(self): - self.location: CodeLocation = CodeLocation() + pass @dataclass @@ -126,4 +124,4 @@ class ProgramNode(Node): relocatable_sections: list[RelocatableSectionNode] absolute_sections: list[AbsoluteSectionNode] shared_externals: list[LabelNode] = field(default_factory=list) - top_instructions: list[LabelNode] = field(default_factory=list) + top_instructions: list[InstructionNode] = field(default_factory=list) diff --git a/cocas/assembler/constants.py b/cocas/assembler/constants.py new file mode 100644 index 00000000..bc63922c --- /dev/null +++ b/cocas/assembler/constants.py @@ -0,0 +1,4 @@ +__all__ = ("DBG_SOURCE_INST", "DBG_LOC_INST") + +DBG_SOURCE_INST = "dbg_source" +DBG_LOC_INST = "dbg_loc" diff --git a/cocas/linker/debug_export.py b/cocas/linker/debug_export.py index 5b87ef8e..91951388 100644 --- a/cocas/linker/debug_export.py +++ b/cocas/linker/debug_export.py @@ -36,7 +36,8 @@ def debug_export(code_locations: dict[int, CodeLocation]) -> str: :param code_locations: mapping from address in binary image to location in source code :return: string with json representation of debug information, code locations are sorted """ - files = sorted(set(map(lambda x: x.file, code_locations.values()))) + code_locations = {addr: cl for addr, cl in code_locations.items() if cl.file is not None} + files = sorted({cl.file for cl in code_locations.values()}) sorted_cl = {key: value for (key, value) in sorted(code_locations.items())} dump = json.dumps({"files": files, "codeLocations": sorted_cl}, default=default_json(files), indent=4, ensure_ascii=False) diff --git a/cocas/object_file/generated/ObjectFileLexer.py b/cocas/object_file/generated/ObjectFileLexer.py index 382a278b..a68542b1 100644 --- a/cocas/object_file/generated/ObjectFileLexer.py +++ b/cocas/object_file/generated/ObjectFileLexer.py @@ -1,4 +1,4 @@ -# Generated from object_file/grammar/ObjectFileLexer.g4 by ANTLR 4.13.1 +# Generated from object_file/grammar/ObjectFileLexer.g4 by ANTLR 4.13.2 from antlr4 import * from io import StringIO import sys @@ -10,80 +10,85 @@ def serializedATN(): return [ - 4,0,26,206,6,-1,6,-1,6,-1,6,-1,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3, - 7,3,2,4,7,4,2,5,7,5,2,6,7,6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2, - 11,7,11,2,12,7,12,2,13,7,13,2,14,7,14,2,15,7,15,2,16,7,16,2,17,7, - 17,2,18,7,18,2,19,7,19,2,20,7,20,2,21,7,21,2,22,7,22,2,23,7,23,2, - 24,7,24,2,25,7,25,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,2,1,2,1,2,1,2,1,2,1,2,1,3,1,3,1,3,1,3,1,4,1,4,1,4,1,4,1,4,1, - 5,1,5,1,5,1,5,1,5,1,6,1,6,1,6,1,6,1,6,1,7,1,7,1,7,1,7,1,7,1,7,1, - 7,1,8,1,8,1,8,1,8,1,9,1,9,1,9,1,9,1,9,1,10,4,10,112,8,10,11,10,12, - 10,113,1,11,1,11,5,11,118,8,11,10,11,12,11,121,9,11,1,11,1,11,5, - 11,125,8,11,10,11,12,11,128,9,11,1,11,1,11,1,12,1,12,1,12,1,12,1, - 12,1,13,1,13,1,14,1,14,1,15,1,15,1,16,1,16,1,17,3,17,146,8,17,1, - 17,4,17,149,8,17,11,17,12,17,150,1,18,4,18,154,8,18,11,18,12,18, - 155,1,18,1,18,1,19,3,19,161,8,19,1,19,4,19,164,8,19,11,19,12,19, - 165,1,19,1,19,1,20,4,20,171,8,20,11,20,12,20,172,1,21,4,21,176,8, - 21,11,21,12,21,177,1,22,4,22,181,8,22,11,22,12,22,182,1,22,1,22, - 1,23,1,23,1,23,1,23,1,23,1,24,4,24,193,8,24,11,24,12,24,194,1,24, - 1,24,1,24,1,25,4,25,201,8,25,11,25,12,25,202,1,25,1,25,0,0,26,5, - 1,7,2,9,3,11,4,13,5,15,6,17,7,19,8,21,9,23,10,25,11,27,12,29,13, - 31,14,33,15,35,16,37,17,39,18,41,19,43,20,45,21,47,22,49,23,51,24, - 53,25,55,26,5,0,1,2,3,4,6,4,0,48,57,65,90,95,95,97,122,3,0,65,90, - 95,95,97,122,5,0,46,46,48,57,65,90,95,95,97,122,2,0,9,9,32,32,6, - 0,9,9,32,32,48,57,65,90,95,95,97,122,2,0,10,10,13,13,214,0,5,1,0, - 0,0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,1,0,0,0,0,13,1,0,0,0,0,15,1,0,0, - 0,0,17,1,0,0,0,0,19,1,0,0,0,0,21,1,0,0,0,0,23,1,0,0,0,0,25,1,0,0, - 0,0,27,1,0,0,0,0,29,1,0,0,0,0,31,1,0,0,0,0,33,1,0,0,0,0,35,1,0,0, - 0,0,37,1,0,0,0,0,39,1,0,0,0,0,41,1,0,0,0,1,43,1,0,0,0,1,45,1,0,0, - 0,2,47,1,0,0,0,2,49,1,0,0,0,2,51,1,0,0,0,3,53,1,0,0,0,4,55,1,0,0, - 0,5,57,1,0,0,0,7,62,1,0,0,0,9,69,1,0,0,0,11,75,1,0,0,0,13,79,1,0, - 0,0,15,84,1,0,0,0,17,89,1,0,0,0,19,94,1,0,0,0,21,101,1,0,0,0,23, - 105,1,0,0,0,25,111,1,0,0,0,27,115,1,0,0,0,29,131,1,0,0,0,31,136, - 1,0,0,0,33,138,1,0,0,0,35,140,1,0,0,0,37,142,1,0,0,0,39,148,1,0, - 0,0,41,153,1,0,0,0,43,163,1,0,0,0,45,170,1,0,0,0,47,175,1,0,0,0, - 49,180,1,0,0,0,51,186,1,0,0,0,53,192,1,0,0,0,55,200,1,0,0,0,57,58, - 5,84,0,0,58,59,5,65,0,0,59,60,5,82,0,0,60,61,5,71,0,0,61,6,1,0,0, - 0,62,63,5,70,0,0,63,64,5,73,0,0,64,65,5,76,0,0,65,66,5,69,0,0,66, - 67,1,0,0,0,67,68,6,1,0,0,68,8,1,0,0,0,69,70,5,65,0,0,70,71,5,66, - 0,0,71,72,5,83,0,0,72,73,1,0,0,0,73,74,6,2,1,0,74,10,1,0,0,0,75, - 76,5,76,0,0,76,77,5,79,0,0,77,78,5,67,0,0,78,12,1,0,0,0,79,80,5, - 78,0,0,80,81,5,84,0,0,81,82,5,82,0,0,82,83,5,89,0,0,83,14,1,0,0, - 0,84,85,5,78,0,0,85,86,5,65,0,0,86,87,5,77,0,0,87,88,5,69,0,0,88, - 16,1,0,0,0,89,90,5,65,0,0,90,91,5,76,0,0,91,92,5,73,0,0,92,93,5, - 71,0,0,93,18,1,0,0,0,94,95,5,68,0,0,95,96,5,65,0,0,96,97,5,84,0, - 0,97,98,5,65,0,0,98,99,1,0,0,0,99,100,6,7,2,0,100,20,1,0,0,0,101, - 102,5,82,0,0,102,103,5,69,0,0,103,104,5,76,0,0,104,22,1,0,0,0,105, - 106,5,88,0,0,106,107,5,84,0,0,107,108,5,82,0,0,108,109,5,78,0,0, - 109,24,1,0,0,0,110,112,7,0,0,0,111,110,1,0,0,0,112,113,1,0,0,0,113, - 111,1,0,0,0,113,114,1,0,0,0,114,26,1,0,0,0,115,119,7,1,0,0,116,118, - 7,0,0,0,117,116,1,0,0,0,118,121,1,0,0,0,119,117,1,0,0,0,119,120, - 1,0,0,0,120,122,1,0,0,0,121,119,1,0,0,0,122,126,3,37,16,0,123,125, - 7,2,0,0,124,123,1,0,0,0,125,128,1,0,0,0,126,124,1,0,0,0,126,127, - 1,0,0,0,127,129,1,0,0,0,128,126,1,0,0,0,129,130,7,0,0,0,130,28,1, - 0,0,0,131,132,5,36,0,0,132,133,5,97,0,0,133,134,5,98,0,0,134,135, - 5,115,0,0,135,30,1,0,0,0,136,137,5,58,0,0,137,32,1,0,0,0,138,139, - 5,45,0,0,139,34,1,0,0,0,140,141,5,43,0,0,141,36,1,0,0,0,142,143, - 5,46,0,0,143,38,1,0,0,0,144,146,5,13,0,0,145,144,1,0,0,0,145,146, - 1,0,0,0,146,147,1,0,0,0,147,149,5,10,0,0,148,145,1,0,0,0,149,150, - 1,0,0,0,150,148,1,0,0,0,150,151,1,0,0,0,151,40,1,0,0,0,152,154,7, - 3,0,0,153,152,1,0,0,0,154,155,1,0,0,0,155,153,1,0,0,0,155,156,1, - 0,0,0,156,157,1,0,0,0,157,158,6,18,3,0,158,42,1,0,0,0,159,161,5, - 13,0,0,160,159,1,0,0,0,160,161,1,0,0,0,161,162,1,0,0,0,162,164,5, - 10,0,0,163,160,1,0,0,0,164,165,1,0,0,0,165,163,1,0,0,0,165,166,1, - 0,0,0,166,167,1,0,0,0,167,168,6,19,4,0,168,44,1,0,0,0,169,171,7, - 4,0,0,170,169,1,0,0,0,171,172,1,0,0,0,172,170,1,0,0,0,172,173,1, - 0,0,0,173,46,1,0,0,0,174,176,7,0,0,0,175,174,1,0,0,0,176,177,1,0, - 0,0,177,175,1,0,0,0,177,178,1,0,0,0,178,48,1,0,0,0,179,181,7,3,0, - 0,180,179,1,0,0,0,181,182,1,0,0,0,182,180,1,0,0,0,182,183,1,0,0, - 0,183,184,1,0,0,0,184,185,6,22,3,0,185,50,1,0,0,0,186,187,5,58,0, - 0,187,188,1,0,0,0,188,189,6,23,4,0,189,190,6,23,2,0,190,52,1,0,0, - 0,191,193,5,32,0,0,192,191,1,0,0,0,193,194,1,0,0,0,194,192,1,0,0, - 0,194,195,1,0,0,0,195,196,1,0,0,0,196,197,6,24,4,0,197,198,6,24, - 5,0,198,54,1,0,0,0,199,201,8,5,0,0,200,199,1,0,0,0,201,202,1,0,0, - 0,202,200,1,0,0,0,202,203,1,0,0,0,203,204,1,0,0,0,204,205,6,25,4, - 0,205,56,1,0,0,0,18,0,1,2,3,4,113,119,126,145,150,155,160,165,172, - 177,182,194,202,6,5,3,0,5,2,0,5,1,0,6,0,0,4,0,0,5,4,0 + 4,0,27,218,6,-1,6,-1,6,-1,6,-1,6,-1,6,-1,2,0,7,0,2,1,7,1,2,2,7,2, + 2,3,7,3,2,4,7,4,2,5,7,5,2,6,7,6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10, + 2,11,7,11,2,12,7,12,2,13,7,13,2,14,7,14,2,15,7,15,2,16,7,16,2,17, + 7,17,2,18,7,18,2,19,7,19,2,20,7,20,2,21,7,21,2,22,7,22,2,23,7,23, + 2,24,7,24,2,25,7,25,2,26,7,26,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,2,1,2,1,2,1,2,1,2,1,2,1,3,1,3,1,3,1,3,1,3,1,3,1, + 4,1,4,1,4,1,4,1,4,1,5,1,5,1,5,1,5,1,5,1,6,1,6,1,6,1,6,1,6,1,7,1, + 7,1,7,1,7,1,7,1,7,1,7,1,8,1,8,1,8,1,8,1,9,1,9,1,9,1,9,1,9,1,10,4, + 10,117,8,10,11,10,12,10,118,1,11,1,11,5,11,123,8,11,10,11,12,11, + 126,9,11,1,11,1,11,5,11,130,8,11,10,11,12,11,133,9,11,1,11,1,11, + 1,12,1,12,1,12,1,12,1,12,1,13,1,13,1,14,1,14,1,15,1,15,1,16,1,16, + 1,17,3,17,151,8,17,1,17,4,17,154,8,17,11,17,12,17,155,1,18,4,18, + 159,8,18,11,18,12,18,160,1,18,1,18,1,19,3,19,166,8,19,1,19,4,19, + 169,8,19,11,19,12,19,170,1,19,1,19,1,20,4,20,176,8,20,11,20,12,20, + 177,1,21,4,21,181,8,21,11,21,12,21,182,1,22,4,22,186,8,22,11,22, + 12,22,187,1,22,1,22,1,23,1,23,1,23,1,23,1,23,1,24,4,24,198,8,24, + 11,24,12,24,199,1,24,1,24,1,24,1,25,4,25,206,8,25,11,25,12,25,207, + 1,25,1,25,1,26,4,26,213,8,26,11,26,12,26,214,1,26,1,26,0,0,27,6, + 1,8,2,10,3,12,4,14,5,16,6,18,7,20,8,22,9,24,10,26,11,28,12,30,13, + 32,14,34,15,36,16,38,17,40,18,42,19,44,20,46,21,48,22,50,23,52,24, + 54,25,56,26,58,27,6,0,1,2,3,4,5,7,4,0,48,57,65,90,95,95,97,122,3, + 0,65,90,95,95,97,122,5,0,46,46,48,57,65,90,95,95,97,122,2,0,9,9, + 32,32,6,0,9,9,32,32,48,57,65,90,95,95,97,122,2,0,10,10,13,13,4,0, + 32,32,48,58,65,70,97,102,226,0,6,1,0,0,0,0,8,1,0,0,0,0,10,1,0,0, + 0,0,12,1,0,0,0,0,14,1,0,0,0,0,16,1,0,0,0,0,18,1,0,0,0,0,20,1,0,0, + 0,0,22,1,0,0,0,0,24,1,0,0,0,0,26,1,0,0,0,0,28,1,0,0,0,0,30,1,0,0, + 0,0,32,1,0,0,0,0,34,1,0,0,0,0,36,1,0,0,0,0,38,1,0,0,0,0,40,1,0,0, + 0,0,42,1,0,0,0,1,44,1,0,0,0,1,46,1,0,0,0,2,48,1,0,0,0,2,50,1,0,0, + 0,2,52,1,0,0,0,3,54,1,0,0,0,4,56,1,0,0,0,5,58,1,0,0,0,6,60,1,0,0, + 0,8,65,1,0,0,0,10,72,1,0,0,0,12,78,1,0,0,0,14,84,1,0,0,0,16,89,1, + 0,0,0,18,94,1,0,0,0,20,99,1,0,0,0,22,106,1,0,0,0,24,110,1,0,0,0, + 26,116,1,0,0,0,28,120,1,0,0,0,30,136,1,0,0,0,32,141,1,0,0,0,34,143, + 1,0,0,0,36,145,1,0,0,0,38,147,1,0,0,0,40,153,1,0,0,0,42,158,1,0, + 0,0,44,168,1,0,0,0,46,175,1,0,0,0,48,180,1,0,0,0,50,185,1,0,0,0, + 52,191,1,0,0,0,54,197,1,0,0,0,56,205,1,0,0,0,58,212,1,0,0,0,60,61, + 5,84,0,0,61,62,5,65,0,0,62,63,5,82,0,0,63,64,5,71,0,0,64,7,1,0,0, + 0,65,66,5,70,0,0,66,67,5,73,0,0,67,68,5,76,0,0,68,69,5,69,0,0,69, + 70,1,0,0,0,70,71,6,1,0,0,71,9,1,0,0,0,72,73,5,65,0,0,73,74,5,66, + 0,0,74,75,5,83,0,0,75,76,1,0,0,0,76,77,6,2,1,0,77,11,1,0,0,0,78, + 79,5,76,0,0,79,80,5,79,0,0,80,81,5,67,0,0,81,82,1,0,0,0,82,83,6, + 3,2,0,83,13,1,0,0,0,84,85,5,78,0,0,85,86,5,84,0,0,86,87,5,82,0,0, + 87,88,5,89,0,0,88,15,1,0,0,0,89,90,5,78,0,0,90,91,5,65,0,0,91,92, + 5,77,0,0,92,93,5,69,0,0,93,17,1,0,0,0,94,95,5,65,0,0,95,96,5,76, + 0,0,96,97,5,73,0,0,97,98,5,71,0,0,98,19,1,0,0,0,99,100,5,68,0,0, + 100,101,5,65,0,0,101,102,5,84,0,0,102,103,5,65,0,0,103,104,1,0,0, + 0,104,105,6,7,3,0,105,21,1,0,0,0,106,107,5,82,0,0,107,108,5,69,0, + 0,108,109,5,76,0,0,109,23,1,0,0,0,110,111,5,88,0,0,111,112,5,84, + 0,0,112,113,5,82,0,0,113,114,5,78,0,0,114,25,1,0,0,0,115,117,7,0, + 0,0,116,115,1,0,0,0,117,118,1,0,0,0,118,116,1,0,0,0,118,119,1,0, + 0,0,119,27,1,0,0,0,120,124,7,1,0,0,121,123,7,0,0,0,122,121,1,0,0, + 0,123,126,1,0,0,0,124,122,1,0,0,0,124,125,1,0,0,0,125,127,1,0,0, + 0,126,124,1,0,0,0,127,131,3,38,16,0,128,130,7,2,0,0,129,128,1,0, + 0,0,130,133,1,0,0,0,131,129,1,0,0,0,131,132,1,0,0,0,132,134,1,0, + 0,0,133,131,1,0,0,0,134,135,7,0,0,0,135,29,1,0,0,0,136,137,5,36, + 0,0,137,138,5,97,0,0,138,139,5,98,0,0,139,140,5,115,0,0,140,31,1, + 0,0,0,141,142,5,58,0,0,142,33,1,0,0,0,143,144,5,45,0,0,144,35,1, + 0,0,0,145,146,5,43,0,0,146,37,1,0,0,0,147,148,5,46,0,0,148,39,1, + 0,0,0,149,151,5,13,0,0,150,149,1,0,0,0,150,151,1,0,0,0,151,152,1, + 0,0,0,152,154,5,10,0,0,153,150,1,0,0,0,154,155,1,0,0,0,155,153,1, + 0,0,0,155,156,1,0,0,0,156,41,1,0,0,0,157,159,7,3,0,0,158,157,1,0, + 0,0,159,160,1,0,0,0,160,158,1,0,0,0,160,161,1,0,0,0,161,162,1,0, + 0,0,162,163,6,18,4,0,163,43,1,0,0,0,164,166,5,13,0,0,165,164,1,0, + 0,0,165,166,1,0,0,0,166,167,1,0,0,0,167,169,5,10,0,0,168,165,1,0, + 0,0,169,170,1,0,0,0,170,168,1,0,0,0,170,171,1,0,0,0,171,172,1,0, + 0,0,172,173,6,19,5,0,173,45,1,0,0,0,174,176,7,4,0,0,175,174,1,0, + 0,0,176,177,1,0,0,0,177,175,1,0,0,0,177,178,1,0,0,0,178,47,1,0,0, + 0,179,181,7,0,0,0,180,179,1,0,0,0,181,182,1,0,0,0,182,180,1,0,0, + 0,182,183,1,0,0,0,183,49,1,0,0,0,184,186,7,3,0,0,185,184,1,0,0,0, + 186,187,1,0,0,0,187,185,1,0,0,0,187,188,1,0,0,0,188,189,1,0,0,0, + 189,190,6,22,4,0,190,51,1,0,0,0,191,192,5,58,0,0,192,193,1,0,0,0, + 193,194,6,23,5,0,194,195,6,23,3,0,195,53,1,0,0,0,196,198,5,32,0, + 0,197,196,1,0,0,0,198,199,1,0,0,0,199,197,1,0,0,0,199,200,1,0,0, + 0,200,201,1,0,0,0,201,202,6,24,5,0,202,203,6,24,6,0,203,55,1,0,0, + 0,204,206,8,5,0,0,205,204,1,0,0,0,206,207,1,0,0,0,207,205,1,0,0, + 0,207,208,1,0,0,0,208,209,1,0,0,0,209,210,6,25,5,0,210,57,1,0,0, + 0,211,213,7,6,0,0,212,211,1,0,0,0,213,214,1,0,0,0,214,212,1,0,0, + 0,214,215,1,0,0,0,215,216,1,0,0,0,216,217,6,26,5,0,217,59,1,0,0, + 0,20,0,1,2,3,4,5,118,124,131,150,155,160,165,170,177,182,187,199, + 207,214,7,5,3,0,5,2,0,5,5,0,5,1,0,6,0,0,4,0,0,5,4,0 ] class ObjectFileLexer(Lexer): @@ -96,6 +101,7 @@ class ObjectFileLexer(Lexer): IN_ABS = 2 IN_FILE = 3 IN_FILEPATH = 4 + IN_LOC = 5 TARG = 1 FILE = 2 @@ -123,10 +129,12 @@ class ObjectFileLexer(Lexer): COLON_ABS = 24 SPACES_FILE = 25 FILEPATH = 26 + LOCS = 27 channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ] - modeNames = [ "DEFAULT_MODE", "IN_BYTES", "IN_ABS", "IN_FILE", "IN_FILEPATH" ] + modeNames = [ "DEFAULT_MODE", "IN_BYTES", "IN_ABS", "IN_FILE", "IN_FILEPATH", + "IN_LOC" ] literalNames = [ "", "'TARG'", "'FILE'", "'ABS'", "'LOC'", "'NTRY'", "'NAME'", "'ALIG'", @@ -136,19 +144,20 @@ class ObjectFileLexer(Lexer): "TARG", "FILE", "ABS", "LOC", "NTRY", "NAME", "ALIG", "DATA", "REL", "XTRN", "WORD", "WORD_WITH_DOTS", "ABS_SECTION", "COLON", "MINUS", "PLUS", "DOT", "NEWLINE", "WS", "NEWLINE_BYTES", "BYTES", - "WORD_ABS", "WS_ABS", "COLON_ABS", "SPACES_FILE", "FILEPATH" ] + "WORD_ABS", "WS_ABS", "COLON_ABS", "SPACES_FILE", "FILEPATH", + "LOCS" ] ruleNames = [ "TARG", "FILE", "ABS", "LOC", "NTRY", "NAME", "ALIG", "DATA", "REL", "XTRN", "WORD", "WORD_WITH_DOTS", "ABS_SECTION", "COLON", "MINUS", "PLUS", "DOT", "NEWLINE", "WS", "NEWLINE_BYTES", "BYTES", "WORD_ABS", "WS_ABS", "COLON_ABS", "SPACES_FILE", - "FILEPATH" ] + "FILEPATH", "LOCS" ] grammarFileName = "ObjectFileLexer.g4" def __init__(self, input=None, output:TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.13.1") + self.checkVersion("4.13.2") self._interp = LexerATNSimulator(self, self.atn, self.decisionsToDFA, PredictionContextCache()) self._actions = None self._predicates = None diff --git a/cocas/object_file/generated/ObjectFileParser.py b/cocas/object_file/generated/ObjectFileParser.py index 06e85b04..4186f85f 100644 --- a/cocas/object_file/generated/ObjectFileParser.py +++ b/cocas/object_file/generated/ObjectFileParser.py @@ -1,4 +1,4 @@ -# Generated from object_file/grammar/ObjectFileParser.g4 by ANTLR 4.13.1 +# Generated from object_file/grammar/ObjectFileParser.g4 by ANTLR 4.13.2 # encoding: utf-8 from antlr4 import * from io import StringIO @@ -10,84 +10,81 @@ def serializedATN(): return [ - 4,1,26,233,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, + 4,1,27,227,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,2,6,7, 6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,13,7,13, 2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,19,2,20, 7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,1,0,3,0,54, - 8,0,1,0,3,0,57,8,0,1,0,4,0,60,8,0,11,0,12,0,61,1,0,1,0,1,1,3,1,67, - 8,1,1,1,1,1,5,1,71,8,1,10,1,12,1,74,9,1,1,1,4,1,77,8,1,11,1,12,1, - 78,3,1,81,8,1,1,1,5,1,84,8,1,10,1,12,1,87,9,1,1,2,1,2,4,2,91,8,2, - 11,2,12,2,92,1,3,1,3,5,3,97,8,3,10,3,12,3,100,9,3,1,4,1,4,3,4,104, - 8,4,1,4,1,4,5,4,108,8,4,10,4,12,4,111,9,4,1,4,3,4,114,8,4,1,4,5, - 4,117,8,4,10,4,12,4,120,9,4,1,5,1,5,1,5,1,5,1,6,1,6,1,6,1,6,1,6, - 1,7,1,7,1,7,1,7,3,7,135,8,7,1,7,4,7,138,8,7,11,7,12,7,139,1,8,1, - 8,5,8,144,8,8,10,8,12,8,147,9,8,1,8,1,8,1,9,1,9,1,9,1,9,1,9,1,10, - 1,10,1,10,1,10,1,11,1,11,1,11,1,11,1,12,1,12,3,12,166,8,12,1,12, - 4,12,169,8,12,11,12,12,12,170,1,13,1,13,5,13,175,8,13,10,13,12,13, - 178,9,13,1,13,1,13,1,14,1,14,1,14,1,14,1,14,1,14,5,14,188,8,14,10, - 14,12,14,191,9,14,1,14,1,14,1,15,1,15,1,16,1,16,1,17,3,17,200,8, - 17,1,17,1,17,1,17,1,17,3,17,206,8,17,3,17,208,8,17,1,18,1,18,1,18, - 1,18,1,19,1,19,1,19,1,20,1,20,1,20,1,20,1,20,1,20,1,21,1,21,1,22, - 1,22,1,23,1,23,1,24,1,24,1,25,1,25,1,25,0,0,26,0,2,4,6,8,10,12,14, - 16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,0,2,1,0,11, - 12,2,0,11,11,13,13,231,0,53,1,0,0,0,2,66,1,0,0,0,4,90,1,0,0,0,6, - 94,1,0,0,0,8,101,1,0,0,0,10,121,1,0,0,0,12,125,1,0,0,0,14,130,1, - 0,0,0,16,141,1,0,0,0,18,150,1,0,0,0,20,155,1,0,0,0,22,159,1,0,0, - 0,24,163,1,0,0,0,26,172,1,0,0,0,28,181,1,0,0,0,30,194,1,0,0,0,32, - 196,1,0,0,0,34,199,1,0,0,0,36,209,1,0,0,0,38,213,1,0,0,0,40,216, - 1,0,0,0,42,222,1,0,0,0,44,224,1,0,0,0,46,226,1,0,0,0,48,228,1,0, - 0,0,50,230,1,0,0,0,52,54,5,18,0,0,53,52,1,0,0,0,53,54,1,0,0,0,54, - 56,1,0,0,0,55,57,3,10,5,0,56,55,1,0,0,0,56,57,1,0,0,0,57,59,1,0, - 0,0,58,60,3,2,1,0,59,58,1,0,0,0,60,61,1,0,0,0,61,59,1,0,0,0,61,62, - 1,0,0,0,62,63,1,0,0,0,63,64,5,0,0,1,64,1,1,0,0,0,65,67,3,12,6,0, - 66,65,1,0,0,0,66,67,1,0,0,0,67,80,1,0,0,0,68,72,3,4,2,0,69,71,3, - 8,4,0,70,69,1,0,0,0,71,74,1,0,0,0,72,70,1,0,0,0,72,73,1,0,0,0,73, - 81,1,0,0,0,74,72,1,0,0,0,75,77,3,8,4,0,76,75,1,0,0,0,77,78,1,0,0, - 0,78,76,1,0,0,0,78,79,1,0,0,0,79,81,1,0,0,0,80,68,1,0,0,0,80,76, - 1,0,0,0,81,85,1,0,0,0,82,84,3,28,14,0,83,82,1,0,0,0,84,87,1,0,0, - 0,85,83,1,0,0,0,85,86,1,0,0,0,86,3,1,0,0,0,87,85,1,0,0,0,88,91,3, - 6,3,0,89,91,3,18,9,0,90,88,1,0,0,0,90,89,1,0,0,0,91,92,1,0,0,0,92, - 90,1,0,0,0,92,93,1,0,0,0,93,5,1,0,0,0,94,98,3,14,7,0,95,97,3,16, - 8,0,96,95,1,0,0,0,97,100,1,0,0,0,98,96,1,0,0,0,98,99,1,0,0,0,99, - 7,1,0,0,0,100,98,1,0,0,0,101,103,3,20,10,0,102,104,3,22,11,0,103, - 102,1,0,0,0,103,104,1,0,0,0,104,105,1,0,0,0,105,109,3,24,12,0,106, - 108,3,16,8,0,107,106,1,0,0,0,108,111,1,0,0,0,109,107,1,0,0,0,109, - 110,1,0,0,0,110,113,1,0,0,0,111,109,1,0,0,0,112,114,3,26,13,0,113, - 112,1,0,0,0,113,114,1,0,0,0,114,118,1,0,0,0,115,117,3,18,9,0,116, - 115,1,0,0,0,117,120,1,0,0,0,118,116,1,0,0,0,118,119,1,0,0,0,119, - 9,1,0,0,0,120,118,1,0,0,0,121,122,5,1,0,0,122,123,3,46,23,0,123, - 124,5,18,0,0,124,11,1,0,0,0,125,126,5,2,0,0,126,127,5,25,0,0,127, - 128,3,32,16,0,128,129,5,18,0,0,129,13,1,0,0,0,130,131,5,3,0,0,131, - 132,3,42,21,0,132,134,5,24,0,0,133,135,3,30,15,0,134,133,1,0,0,0, - 134,135,1,0,0,0,135,137,1,0,0,0,136,138,5,20,0,0,137,136,1,0,0,0, - 138,139,1,0,0,0,139,137,1,0,0,0,139,140,1,0,0,0,140,15,1,0,0,0,141, - 145,5,4,0,0,142,144,3,40,20,0,143,142,1,0,0,0,144,147,1,0,0,0,145, - 143,1,0,0,0,145,146,1,0,0,0,146,148,1,0,0,0,147,145,1,0,0,0,148, - 149,5,18,0,0,149,17,1,0,0,0,150,151,5,5,0,0,151,152,3,46,23,0,152, - 153,3,44,22,0,153,154,5,18,0,0,154,19,1,0,0,0,155,156,5,6,0,0,156, - 157,3,48,24,0,157,158,5,18,0,0,158,21,1,0,0,0,159,160,5,7,0,0,160, - 161,3,44,22,0,161,162,5,18,0,0,162,23,1,0,0,0,163,165,5,8,0,0,164, - 166,3,30,15,0,165,164,1,0,0,0,165,166,1,0,0,0,166,168,1,0,0,0,167, - 169,5,20,0,0,168,167,1,0,0,0,169,170,1,0,0,0,170,168,1,0,0,0,170, - 171,1,0,0,0,171,25,1,0,0,0,172,176,5,9,0,0,173,175,3,34,17,0,174, - 173,1,0,0,0,175,178,1,0,0,0,176,174,1,0,0,0,176,177,1,0,0,0,177, - 179,1,0,0,0,178,176,1,0,0,0,179,180,5,18,0,0,180,27,1,0,0,0,181, - 182,5,10,0,0,182,183,3,46,23,0,183,189,5,14,0,0,184,185,3,48,24, - 0,185,186,3,34,17,0,186,188,1,0,0,0,187,184,1,0,0,0,188,191,1,0, - 0,0,189,187,1,0,0,0,189,190,1,0,0,0,190,192,1,0,0,0,191,189,1,0, - 0,0,192,193,5,18,0,0,193,29,1,0,0,0,194,195,5,21,0,0,195,31,1,0, - 0,0,196,197,5,26,0,0,197,33,1,0,0,0,198,200,3,50,25,0,199,198,1, - 0,0,0,199,200,1,0,0,0,200,201,1,0,0,0,201,207,3,44,22,0,202,203, - 5,14,0,0,203,205,3,36,18,0,204,206,3,38,19,0,205,204,1,0,0,0,205, - 206,1,0,0,0,206,208,1,0,0,0,207,202,1,0,0,0,207,208,1,0,0,0,208, - 35,1,0,0,0,209,210,3,44,22,0,210,211,5,14,0,0,211,212,3,44,22,0, - 212,37,1,0,0,0,213,214,5,16,0,0,214,215,3,44,22,0,215,39,1,0,0,0, - 216,217,3,44,22,0,217,218,5,14,0,0,218,219,3,44,22,0,219,220,5,14, - 0,0,220,221,3,44,22,0,221,41,1,0,0,0,222,223,5,22,0,0,223,43,1,0, - 0,0,224,225,5,11,0,0,225,45,1,0,0,0,226,227,7,0,0,0,227,47,1,0,0, - 0,228,229,7,1,0,0,229,49,1,0,0,0,230,231,5,15,0,0,231,51,1,0,0,0, - 25,53,56,61,66,72,78,80,85,90,92,98,103,109,113,118,134,139,145, - 165,170,176,189,199,205,207 + 8,0,1,0,3,0,57,8,0,1,0,4,0,60,8,0,11,0,12,0,61,1,0,1,0,1,1,5,1,67, + 8,1,10,1,12,1,70,9,1,1,1,1,1,5,1,74,8,1,10,1,12,1,77,9,1,1,1,4,1, + 80,8,1,11,1,12,1,81,3,1,84,8,1,1,1,5,1,87,8,1,10,1,12,1,90,9,1,1, + 2,1,2,4,2,94,8,2,11,2,12,2,95,1,3,1,3,5,3,100,8,3,10,3,12,3,103, + 9,3,1,4,1,4,3,4,107,8,4,1,4,1,4,5,4,111,8,4,10,4,12,4,114,9,4,1, + 4,3,4,117,8,4,1,4,5,4,120,8,4,10,4,12,4,123,9,4,1,5,1,5,1,5,1,5, + 1,6,1,6,1,6,1,6,1,6,1,7,1,7,1,7,1,7,3,7,138,8,7,1,7,4,7,141,8,7, + 11,7,12,7,142,1,8,1,8,1,8,1,8,1,9,1,9,1,9,1,9,1,9,1,10,1,10,1,10, + 1,10,1,11,1,11,1,11,1,11,1,12,1,12,3,12,164,8,12,1,12,4,12,167,8, + 12,11,12,12,12,168,1,13,1,13,5,13,173,8,13,10,13,12,13,176,9,13, + 1,13,1,13,1,14,1,14,1,14,1,14,1,14,1,14,5,14,186,8,14,10,14,12,14, + 189,9,14,1,14,1,14,1,15,1,15,1,16,1,16,1,17,3,17,198,8,17,1,17,1, + 17,1,17,1,17,3,17,204,8,17,3,17,206,8,17,1,18,1,18,1,18,1,18,1,19, + 1,19,1,19,1,20,1,20,1,21,1,21,1,22,1,22,1,23,1,23,1,24,1,24,1,25, + 1,25,1,25,0,0,26,0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34, + 36,38,40,42,44,46,48,50,0,2,1,0,11,12,2,0,11,11,13,13,224,0,53,1, + 0,0,0,2,68,1,0,0,0,4,93,1,0,0,0,6,97,1,0,0,0,8,104,1,0,0,0,10,124, + 1,0,0,0,12,128,1,0,0,0,14,133,1,0,0,0,16,144,1,0,0,0,18,148,1,0, + 0,0,20,153,1,0,0,0,22,157,1,0,0,0,24,161,1,0,0,0,26,170,1,0,0,0, + 28,179,1,0,0,0,30,192,1,0,0,0,32,194,1,0,0,0,34,197,1,0,0,0,36,207, + 1,0,0,0,38,211,1,0,0,0,40,214,1,0,0,0,42,216,1,0,0,0,44,218,1,0, + 0,0,46,220,1,0,0,0,48,222,1,0,0,0,50,224,1,0,0,0,52,54,5,18,0,0, + 53,52,1,0,0,0,53,54,1,0,0,0,54,56,1,0,0,0,55,57,3,10,5,0,56,55,1, + 0,0,0,56,57,1,0,0,0,57,59,1,0,0,0,58,60,3,2,1,0,59,58,1,0,0,0,60, + 61,1,0,0,0,61,59,1,0,0,0,61,62,1,0,0,0,62,63,1,0,0,0,63,64,5,0,0, + 1,64,1,1,0,0,0,65,67,3,12,6,0,66,65,1,0,0,0,67,70,1,0,0,0,68,66, + 1,0,0,0,68,69,1,0,0,0,69,83,1,0,0,0,70,68,1,0,0,0,71,75,3,4,2,0, + 72,74,3,8,4,0,73,72,1,0,0,0,74,77,1,0,0,0,75,73,1,0,0,0,75,76,1, + 0,0,0,76,84,1,0,0,0,77,75,1,0,0,0,78,80,3,8,4,0,79,78,1,0,0,0,80, + 81,1,0,0,0,81,79,1,0,0,0,81,82,1,0,0,0,82,84,1,0,0,0,83,71,1,0,0, + 0,83,79,1,0,0,0,84,88,1,0,0,0,85,87,3,28,14,0,86,85,1,0,0,0,87,90, + 1,0,0,0,88,86,1,0,0,0,88,89,1,0,0,0,89,3,1,0,0,0,90,88,1,0,0,0,91, + 94,3,6,3,0,92,94,3,18,9,0,93,91,1,0,0,0,93,92,1,0,0,0,94,95,1,0, + 0,0,95,93,1,0,0,0,95,96,1,0,0,0,96,5,1,0,0,0,97,101,3,14,7,0,98, + 100,3,16,8,0,99,98,1,0,0,0,100,103,1,0,0,0,101,99,1,0,0,0,101,102, + 1,0,0,0,102,7,1,0,0,0,103,101,1,0,0,0,104,106,3,20,10,0,105,107, + 3,22,11,0,106,105,1,0,0,0,106,107,1,0,0,0,107,108,1,0,0,0,108,112, + 3,24,12,0,109,111,3,16,8,0,110,109,1,0,0,0,111,114,1,0,0,0,112,110, + 1,0,0,0,112,113,1,0,0,0,113,116,1,0,0,0,114,112,1,0,0,0,115,117, + 3,26,13,0,116,115,1,0,0,0,116,117,1,0,0,0,117,121,1,0,0,0,118,120, + 3,18,9,0,119,118,1,0,0,0,120,123,1,0,0,0,121,119,1,0,0,0,121,122, + 1,0,0,0,122,9,1,0,0,0,123,121,1,0,0,0,124,125,5,1,0,0,125,126,3, + 46,23,0,126,127,5,18,0,0,127,11,1,0,0,0,128,129,5,2,0,0,129,130, + 5,25,0,0,130,131,3,32,16,0,131,132,5,18,0,0,132,13,1,0,0,0,133,134, + 5,3,0,0,134,135,3,42,21,0,135,137,5,24,0,0,136,138,3,30,15,0,137, + 136,1,0,0,0,137,138,1,0,0,0,138,140,1,0,0,0,139,141,5,20,0,0,140, + 139,1,0,0,0,141,142,1,0,0,0,142,140,1,0,0,0,142,143,1,0,0,0,143, + 15,1,0,0,0,144,145,5,4,0,0,145,146,3,40,20,0,146,147,5,18,0,0,147, + 17,1,0,0,0,148,149,5,5,0,0,149,150,3,46,23,0,150,151,3,44,22,0,151, + 152,5,18,0,0,152,19,1,0,0,0,153,154,5,6,0,0,154,155,3,48,24,0,155, + 156,5,18,0,0,156,21,1,0,0,0,157,158,5,7,0,0,158,159,3,44,22,0,159, + 160,5,18,0,0,160,23,1,0,0,0,161,163,5,8,0,0,162,164,3,30,15,0,163, + 162,1,0,0,0,163,164,1,0,0,0,164,166,1,0,0,0,165,167,5,20,0,0,166, + 165,1,0,0,0,167,168,1,0,0,0,168,166,1,0,0,0,168,169,1,0,0,0,169, + 25,1,0,0,0,170,174,5,9,0,0,171,173,3,34,17,0,172,171,1,0,0,0,173, + 176,1,0,0,0,174,172,1,0,0,0,174,175,1,0,0,0,175,177,1,0,0,0,176, + 174,1,0,0,0,177,178,5,18,0,0,178,27,1,0,0,0,179,180,5,10,0,0,180, + 181,3,46,23,0,181,187,5,14,0,0,182,183,3,48,24,0,183,184,3,34,17, + 0,184,186,1,0,0,0,185,182,1,0,0,0,186,189,1,0,0,0,187,185,1,0,0, + 0,187,188,1,0,0,0,188,190,1,0,0,0,189,187,1,0,0,0,190,191,5,18,0, + 0,191,29,1,0,0,0,192,193,5,21,0,0,193,31,1,0,0,0,194,195,5,26,0, + 0,195,33,1,0,0,0,196,198,3,50,25,0,197,196,1,0,0,0,197,198,1,0,0, + 0,198,199,1,0,0,0,199,205,3,44,22,0,200,201,5,14,0,0,201,203,3,36, + 18,0,202,204,3,38,19,0,203,202,1,0,0,0,203,204,1,0,0,0,204,206,1, + 0,0,0,205,200,1,0,0,0,205,206,1,0,0,0,206,35,1,0,0,0,207,208,3,44, + 22,0,208,209,5,14,0,0,209,210,3,44,22,0,210,37,1,0,0,0,211,212,5, + 16,0,0,212,213,3,44,22,0,213,39,1,0,0,0,214,215,5,27,0,0,215,41, + 1,0,0,0,216,217,5,22,0,0,217,43,1,0,0,0,218,219,5,11,0,0,219,45, + 1,0,0,0,220,221,7,0,0,0,221,47,1,0,0,0,222,223,7,1,0,0,223,49,1, + 0,0,0,224,225,5,15,0,0,225,51,1,0,0,0,24,53,56,61,68,75,81,83,88, + 93,95,101,106,112,116,121,137,142,163,168,174,187,197,203,205 ] class ObjectFileParser ( Parser ): @@ -109,7 +106,7 @@ class ObjectFileParser ( Parser ): "NAME", "ALIG", "DATA", "REL", "XTRN", "WORD", "WORD_WITH_DOTS", "ABS_SECTION", "COLON", "MINUS", "PLUS", "DOT", "NEWLINE", "WS", "NEWLINE_BYTES", "BYTES", "WORD_ABS", "WS_ABS", - "COLON_ABS", "SPACES_FILE", "FILEPATH" ] + "COLON_ABS", "SPACES_FILE", "FILEPATH", "LOCS" ] RULE_object_file = 0 RULE_object_block = 1 @@ -131,7 +128,7 @@ class ObjectFileParser ( Parser ): RULE_entry_usage = 17 RULE_range = 18 RULE_lower_part = 19 - RULE_location = 20 + RULE_locations = 20 RULE_abs_address = 21 RULE_number = 22 RULE_label = 23 @@ -142,7 +139,7 @@ class ObjectFileParser ( Parser ): "rsect_block", "targ_record", "source_record", "abs_record", "loc_record", "ntry_record", "name_record", "alig_record", "data_record", "rel_record", "xtrn_record", "data", "filepath", - "entry_usage", "range", "lower_part", "location", "abs_address", + "entry_usage", "range", "lower_part", "locations", "abs_address", "number", "label", "section", "minus" ] EOF = Token.EOF @@ -172,10 +169,11 @@ class ObjectFileParser ( Parser ): COLON_ABS=24 SPACES_FILE=25 FILEPATH=26 + LOCS=27 def __init__(self, input:TokenStream, output:TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.13.1") + self.checkVersion("4.13.2") self._interp = ParserATNSimulator(self, self.atn, self.decisionsToDFA, self.sharedContextCache) self._predicates = None @@ -275,8 +273,11 @@ def asect_block(self): return self.getTypedRuleContext(ObjectFileParser.Asect_blockContext,0) - def source_record(self): - return self.getTypedRuleContext(ObjectFileParser.Source_recordContext,0) + def source_record(self, i:int=None): + if i is None: + return self.getTypedRuleContexts(ObjectFileParser.Source_recordContext) + else: + return self.getTypedRuleContext(ObjectFileParser.Source_recordContext,i) def xtrn_record(self, i:int=None): @@ -312,44 +313,46 @@ def object_block(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 66 + self.state = 68 self._errHandler.sync(self) _la = self._input.LA(1) - if _la==2: + while _la==2: self.state = 65 self.source_record() + self.state = 70 + self._errHandler.sync(self) + _la = self._input.LA(1) - - self.state = 80 + self.state = 83 self._errHandler.sync(self) token = self._input.LA(1) if token in [3, 5]: - self.state = 68 + self.state = 71 self.asect_block() - self.state = 72 + self.state = 75 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,4,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 69 + self.state = 72 self.rsect_block() - self.state = 74 + self.state = 77 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,4,self._ctx) pass elif token in [6]: - self.state = 76 + self.state = 79 self._errHandler.sync(self) _alt = 1 while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt == 1: - self.state = 75 + self.state = 78 self.rsect_block() else: raise NoViableAltException(self) - self.state = 78 + self.state = 81 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,5,self._ctx) @@ -357,13 +360,13 @@ def object_block(self): else: raise NoViableAltException(self) - self.state = 85 + self.state = 88 self._errHandler.sync(self) _la = self._input.LA(1) while _la==10: - self.state = 82 + self.state = 85 self.xtrn_record() - self.state = 87 + self.state = 90 self._errHandler.sync(self) _la = self._input.LA(1) @@ -415,20 +418,20 @@ def asect_block(self): self.enterRule(localctx, 4, self.RULE_asect_block) try: self.enterOuterAlt(localctx, 1) - self.state = 90 + self.state = 93 self._errHandler.sync(self) _alt = 1 while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt == 1: - self.state = 90 + self.state = 93 self._errHandler.sync(self) token = self._input.LA(1) if token in [3]: - self.state = 88 + self.state = 91 self.abs_block() pass elif token in [5]: - self.state = 89 + self.state = 92 self.ntry_record() pass else: @@ -437,7 +440,7 @@ def asect_block(self): else: raise NoViableAltException(self) - self.state = 92 + self.state = 95 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,9,self._ctx) @@ -487,15 +490,15 @@ def abs_block(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 94 + self.state = 97 self.abs_record() - self.state = 98 + self.state = 101 self._errHandler.sync(self) _la = self._input.LA(1) while _la==4: - self.state = 95 + self.state = 98 self.loc_record() - self.state = 100 + self.state = 103 self._errHandler.sync(self) _la = self._input.LA(1) @@ -564,44 +567,44 @@ def rsect_block(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 101 + self.state = 104 self.name_record() - self.state = 103 + self.state = 106 self._errHandler.sync(self) _la = self._input.LA(1) if _la==7: - self.state = 102 + self.state = 105 self.alig_record() - self.state = 105 + self.state = 108 self.data_record() - self.state = 109 + self.state = 112 self._errHandler.sync(self) _la = self._input.LA(1) while _la==4: - self.state = 106 + self.state = 109 self.loc_record() - self.state = 111 + self.state = 114 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 113 + self.state = 116 self._errHandler.sync(self) _la = self._input.LA(1) if _la==9: - self.state = 112 + self.state = 115 self.rel_record() - self.state = 118 + self.state = 121 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,14,self._ctx) while _alt!=2 and _alt!=ATN.INVALID_ALT_NUMBER: if _alt==1: - self.state = 115 + self.state = 118 self.ntry_record() - self.state = 120 + self.state = 123 self._errHandler.sync(self) _alt = self._interp.adaptivePredict(self._input,14,self._ctx) @@ -649,11 +652,11 @@ def targ_record(self): self.enterRule(localctx, 10, self.RULE_targ_record) try: self.enterOuterAlt(localctx, 1) - self.state = 121 + self.state = 124 self.match(ObjectFileParser.TARG) - self.state = 122 + self.state = 125 self.label() - self.state = 123 + self.state = 126 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -702,13 +705,13 @@ def source_record(self): self.enterRule(localctx, 12, self.RULE_source_record) try: self.enterOuterAlt(localctx, 1) - self.state = 125 + self.state = 128 self.match(ObjectFileParser.FILE) - self.state = 126 + self.state = 129 self.match(ObjectFileParser.SPACES_FILE) - self.state = 127 + self.state = 130 self.filepath() - self.state = 128 + self.state = 131 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -765,27 +768,27 @@ def abs_record(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 130 + self.state = 133 self.match(ObjectFileParser.ABS) - self.state = 131 + self.state = 134 self.abs_address() - self.state = 132 + self.state = 135 self.match(ObjectFileParser.COLON_ABS) - self.state = 134 + self.state = 137 self._errHandler.sync(self) _la = self._input.LA(1) if _la==21: - self.state = 133 + self.state = 136 self.data() - self.state = 137 + self.state = 140 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 136 + self.state = 139 self.match(ObjectFileParser.NEWLINE_BYTES) - self.state = 139 + self.state = 142 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==20): @@ -810,15 +813,12 @@ def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): def LOC(self): return self.getToken(ObjectFileParser.LOC, 0) - def NEWLINE(self): - return self.getToken(ObjectFileParser.NEWLINE, 0) + def locations(self): + return self.getTypedRuleContext(ObjectFileParser.LocationsContext,0) - def location(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(ObjectFileParser.LocationContext) - else: - return self.getTypedRuleContext(ObjectFileParser.LocationContext,i) + def NEWLINE(self): + return self.getToken(ObjectFileParser.NEWLINE, 0) def getRuleIndex(self): return ObjectFileParser.RULE_loc_record @@ -836,22 +836,13 @@ def loc_record(self): localctx = ObjectFileParser.Loc_recordContext(self, self._ctx, self.state) self.enterRule(localctx, 16, self.RULE_loc_record) - self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 141 + self.state = 144 self.match(ObjectFileParser.LOC) self.state = 145 - self._errHandler.sync(self) - _la = self._input.LA(1) - while _la==11: - self.state = 142 - self.location() - self.state = 147 - self._errHandler.sync(self) - _la = self._input.LA(1) - - self.state = 148 + self.locations() + self.state = 146 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -901,13 +892,13 @@ def ntry_record(self): self.enterRule(localctx, 18, self.RULE_ntry_record) try: self.enterOuterAlt(localctx, 1) - self.state = 150 + self.state = 148 self.match(ObjectFileParser.NTRY) - self.state = 151 + self.state = 149 self.label() - self.state = 152 + self.state = 150 self.number() - self.state = 153 + self.state = 151 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -953,11 +944,11 @@ def name_record(self): self.enterRule(localctx, 20, self.RULE_name_record) try: self.enterOuterAlt(localctx, 1) - self.state = 155 + self.state = 153 self.match(ObjectFileParser.NAME) - self.state = 156 + self.state = 154 self.section() - self.state = 157 + self.state = 155 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -1003,11 +994,11 @@ def alig_record(self): self.enterRule(localctx, 22, self.RULE_alig_record) try: self.enterOuterAlt(localctx, 1) - self.state = 159 + self.state = 157 self.match(ObjectFileParser.ALIG) - self.state = 160 + self.state = 158 self.number() - self.state = 161 + self.state = 159 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -1057,23 +1048,23 @@ def data_record(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 163 + self.state = 161 self.match(ObjectFileParser.DATA) - self.state = 165 + self.state = 163 self._errHandler.sync(self) _la = self._input.LA(1) if _la==21: - self.state = 164 + self.state = 162 self.data() - self.state = 168 + self.state = 166 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 167 + self.state = 165 self.match(ObjectFileParser.NEWLINE_BYTES) - self.state = 170 + self.state = 168 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la==20): @@ -1127,19 +1118,19 @@ def rel_record(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 172 + self.state = 170 self.match(ObjectFileParser.REL) - self.state = 176 + self.state = 174 self._errHandler.sync(self) _la = self._input.LA(1) while _la==11 or _la==15: - self.state = 173 + self.state = 171 self.entry_usage() - self.state = 178 + self.state = 176 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 179 + self.state = 177 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -1203,25 +1194,25 @@ def xtrn_record(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 181 + self.state = 179 self.match(ObjectFileParser.XTRN) - self.state = 182 + self.state = 180 self.label() - self.state = 183 + self.state = 181 self.match(ObjectFileParser.COLON) - self.state = 189 + self.state = 187 self._errHandler.sync(self) _la = self._input.LA(1) while _la==11 or _la==13: - self.state = 184 + self.state = 182 self.section() - self.state = 185 + self.state = 183 self.entry_usage() - self.state = 191 + self.state = 189 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 192 + self.state = 190 self.match(ObjectFileParser.NEWLINE) except RecognitionException as re: localctx.exception = re @@ -1260,7 +1251,7 @@ def data(self): self.enterRule(localctx, 30, self.RULE_data) try: self.enterOuterAlt(localctx, 1) - self.state = 194 + self.state = 192 self.match(ObjectFileParser.BYTES) except RecognitionException as re: localctx.exception = re @@ -1299,7 +1290,7 @@ def filepath(self): self.enterRule(localctx, 32, self.RULE_filepath) try: self.enterOuterAlt(localctx, 1) - self.state = 196 + self.state = 194 self.match(ObjectFileParser.FILEPATH) except RecognitionException as re: localctx.exception = re @@ -1355,29 +1346,29 @@ def entry_usage(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 199 + self.state = 197 self._errHandler.sync(self) _la = self._input.LA(1) if _la==15: - self.state = 198 + self.state = 196 self.minus() - self.state = 201 + self.state = 199 self.number() - self.state = 207 + self.state = 205 self._errHandler.sync(self) _la = self._input.LA(1) if _la==14: - self.state = 202 + self.state = 200 self.match(ObjectFileParser.COLON) - self.state = 203 + self.state = 201 self.range_() - self.state = 205 + self.state = 203 self._errHandler.sync(self) _la = self._input.LA(1) if _la==16: - self.state = 204 + self.state = 202 self.lower_part() @@ -1427,11 +1418,11 @@ def range_(self): self.enterRule(localctx, 36, self.RULE_range) try: self.enterOuterAlt(localctx, 1) - self.state = 209 + self.state = 207 self.number() - self.state = 210 + self.state = 208 self.match(ObjectFileParser.COLON) - self.state = 211 + self.state = 209 self.number() except RecognitionException as re: localctx.exception = re @@ -1474,9 +1465,9 @@ def lower_part(self): self.enterRule(localctx, 38, self.RULE_lower_part) try: self.enterOuterAlt(localctx, 1) - self.state = 213 + self.state = 211 self.match(ObjectFileParser.PLUS) - self.state = 214 + self.state = 212 self.number() except RecognitionException as re: localctx.exception = re @@ -1487,54 +1478,36 @@ def lower_part(self): return localctx - class LocationContext(ParserRuleContext): + class LocationsContext(ParserRuleContext): __slots__ = 'parser' def __init__(self, parser, parent:ParserRuleContext=None, invokingState:int=-1): super().__init__(parent, invokingState) self.parser = parser - def number(self, i:int=None): - if i is None: - return self.getTypedRuleContexts(ObjectFileParser.NumberContext) - else: - return self.getTypedRuleContext(ObjectFileParser.NumberContext,i) - - - def COLON(self, i:int=None): - if i is None: - return self.getTokens(ObjectFileParser.COLON) - else: - return self.getToken(ObjectFileParser.COLON, i) + def LOCS(self): + return self.getToken(ObjectFileParser.LOCS, 0) def getRuleIndex(self): - return ObjectFileParser.RULE_location + return ObjectFileParser.RULE_locations def accept(self, visitor:ParseTreeVisitor): - if hasattr( visitor, "visitLocation" ): - return visitor.visitLocation(self) + if hasattr( visitor, "visitLocations" ): + return visitor.visitLocations(self) else: return visitor.visitChildren(self) - def location(self): + def locations(self): - localctx = ObjectFileParser.LocationContext(self, self._ctx, self.state) - self.enterRule(localctx, 40, self.RULE_location) + localctx = ObjectFileParser.LocationsContext(self, self._ctx, self.state) + self.enterRule(localctx, 40, self.RULE_locations) try: self.enterOuterAlt(localctx, 1) - self.state = 216 - self.number() - self.state = 217 - self.match(ObjectFileParser.COLON) - self.state = 218 - self.number() - self.state = 219 - self.match(ObjectFileParser.COLON) - self.state = 220 - self.number() + self.state = 214 + self.match(ObjectFileParser.LOCS) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -1572,7 +1545,7 @@ def abs_address(self): self.enterRule(localctx, 42, self.RULE_abs_address) try: self.enterOuterAlt(localctx, 1) - self.state = 222 + self.state = 216 self.match(ObjectFileParser.WORD_ABS) except RecognitionException as re: localctx.exception = re @@ -1611,7 +1584,7 @@ def number(self): self.enterRule(localctx, 44, self.RULE_number) try: self.enterOuterAlt(localctx, 1) - self.state = 224 + self.state = 218 self.match(ObjectFileParser.WORD) except RecognitionException as re: localctx.exception = re @@ -1654,7 +1627,7 @@ def label(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 226 + self.state = 220 _la = self._input.LA(1) if not(_la==11 or _la==12): self._errHandler.recoverInline(self) @@ -1702,7 +1675,7 @@ def section(self): self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 228 + self.state = 222 _la = self._input.LA(1) if not(_la==11 or _la==13): self._errHandler.recoverInline(self) @@ -1746,7 +1719,7 @@ def minus(self): self.enterRule(localctx, 50, self.RULE_minus) try: self.enterOuterAlt(localctx, 1) - self.state = 230 + self.state = 224 self.match(ObjectFileParser.MINUS) except RecognitionException as re: localctx.exception = re diff --git a/cocas/object_file/generated/ObjectFileParserVisitor.py b/cocas/object_file/generated/ObjectFileParserVisitor.py index 615aefb0..8a113070 100644 --- a/cocas/object_file/generated/ObjectFileParserVisitor.py +++ b/cocas/object_file/generated/ObjectFileParserVisitor.py @@ -1,4 +1,4 @@ -# Generated from object_file/grammar/ObjectFileParser.g4 by ANTLR 4.13.1 +# Generated from object_file/grammar/ObjectFileParser.g4 by ANTLR 4.13.2 from antlr4 import * if "." in __name__: from .ObjectFileParser import ObjectFileParser @@ -109,8 +109,8 @@ def visitLower_part(self, ctx:ObjectFileParser.Lower_partContext): return self.visitChildren(ctx) - # Visit a parse tree produced by ObjectFileParser#location. - def visitLocation(self, ctx:ObjectFileParser.LocationContext): + # Visit a parse tree produced by ObjectFileParser#locations. + def visitLocations(self, ctx:ObjectFileParser.LocationsContext): return self.visitChildren(ctx) diff --git a/cocas/object_file/grammar/ObjectFileLexer.g4 b/cocas/object_file/grammar/ObjectFileLexer.g4 index 9fd9492c..6220b417 100644 --- a/cocas/object_file/grammar/ObjectFileLexer.g4 +++ b/cocas/object_file/grammar/ObjectFileLexer.g4 @@ -3,7 +3,7 @@ lexer grammar ObjectFileLexer; TARG: 'TARG'; FILE: 'FILE' -> pushMode(IN_FILE); ABS : 'ABS' -> pushMode(IN_ABS); -LOC: 'LOC'; +LOC: 'LOC' -> pushMode(IN_LOC); NTRY: 'NTRY'; NAME: 'NAME'; ALIG: 'ALIG'; @@ -37,4 +37,7 @@ mode IN_FILE; SPACES_FILE: ' '+ -> popMode, pushMode(IN_FILEPATH); mode IN_FILEPATH; -FILEPATH: ~[\r\n]+ -> popMode; \ No newline at end of file +FILEPATH: ~[\r\n]+ -> popMode; + +mode IN_LOC; +LOCS: [0-9a-fA-F: ]+ -> popMode; diff --git a/cocas/object_file/grammar/ObjectFileParser.g4 b/cocas/object_file/grammar/ObjectFileParser.g4 index ae4720c6..4d2fa09a 100644 --- a/cocas/object_file/grammar/ObjectFileParser.g4 +++ b/cocas/object_file/grammar/ObjectFileParser.g4 @@ -10,7 +10,7 @@ object_file: ; object_block: - source_record? + source_record* ( asect_block rsect_block* | rsect_block+ @@ -39,7 +39,7 @@ rsect_block: targ_record: TARG label NEWLINE; source_record: FILE SPACES_FILE filepath NEWLINE; abs_record: ABS abs_address COLON_ABS data? NEWLINE_BYTES+; -loc_record: LOC location* NEWLINE; +loc_record: LOC locations NEWLINE; ntry_record: NTRY label number NEWLINE; name_record: NAME section NEWLINE; alig_record: ALIG number NEWLINE; @@ -52,7 +52,7 @@ filepath: FILEPATH; entry_usage: minus? number (COLON range lower_part?)?; range: number COLON number; lower_part: PLUS number; -location: number COLON number COLON number; +locations: LOCS; abs_address: WORD_ABS; number: WORD; diff --git a/cocas/object_file/object_import.py b/cocas/object_file/object_import.py index 26a813a1..a5f75279 100644 --- a/cocas/object_file/object_import.py +++ b/cocas/object_file/object_import.py @@ -1,12 +1,15 @@ import bisect import codecs +import itertools +from collections.abc import Iterator from pathlib import Path -from typing import Optional, Union +from typing import Optional, Union, cast import antlr4 from antlr4 import CommonTokenStream, InputStream from cocas.object_module import CodeLocation, ExternalEntry, ObjectModule, ObjectSectionRecord +from cocas.object_module.object_module import ObjectSectionRecord from .exceptions import AntlrErrorListener, ObjectFileException from .generated import ObjectFileLexer, ObjectFileParser, ObjectFileParserVisitor @@ -35,23 +38,27 @@ def visitObject_file(self, ctx: ObjectFileParser.Object_fileContext) -> list[Obj raise ObjectFileException(self.file, ctx.start.line, f'Expected non-empty target header for {target_name}, got empty') - modules = [] + modules: list[ObjectModule] = [] for i in ctx.object_block(): modules.append(self.visitObject_block(i)) return modules def visitObject_block(self, ctx: ObjectFileParser.Object_blockContext) -> ObjectModule: - if ctx.source_record(): - filename = self.visitSource_record(ctx.source_record()) - else: - filename = None + legacy_source_path: str | None = None + source_paths_table: list[Path] = [] + + if source_records := ctx.source_record(): + record_iter: Iterator[ObjectFileParser.Source_recordContext] = iter(source_records) + legacy_source_path = self.visitSource_record(next(record_iter)) + source_paths_table = [Path(self.visitSource_record(r)) for r in record_iter] + source_paths_table.insert(0, Path(legacy_source_path)) if ctx.asect_block(): asects, asect_addr = self.visitAsect_block(ctx.asect_block()) else: asects, asect_addr = {}, [] - rsects = {} + rsects: dict[str, ObjectSectionRecord] = {} for block in ctx.rsect_block(): name, rsect = self.visitRsect_block(block) if name in rsects: @@ -73,11 +80,12 @@ def visitObject_block(self, ctx: ObjectFileParser.Object_blockContext) -> Object rsects[sect].external[label].append(entry) else: raise ObjectFileException(self.file, xtrn.start.line, f'Section not found: {sect}') - if filename: - f = Path(filename) - for i in (asects | rsects).values(): - for j in i.code_locations.values(): - j.file = f.as_posix() + if legacy_source_path: + f = Path(legacy_source_path) + for sect in itertools.chain(asects.values(), rsects.values()): + for loc in sect.code_locations.values(): + if isinstance(loc.file, int): + loc.file = source_paths_table[loc.file].as_posix() om = ObjectModule(list(asects.values()), list(rsects.values()), f) else: for i in (asects | rsects).values(): @@ -85,8 +93,11 @@ def visitObject_block(self, ctx: ObjectFileParser.Object_blockContext) -> Object om = ObjectModule(list(asects.values()), list(rsects.values()), None) return om - def visitAsect_block(self, ctx: ObjectFileParser.Asect_blockContext): - asects = {} + def visitAsect_block( + self, + ctx: ObjectFileParser.Asect_blockContext, + ) -> tuple[dict[int, ObjectSectionRecord], list[int]]: + asects: dict[int, ObjectSectionRecord] = {} for addr, record in map(self.visitAbs_block, ctx.abs_block()): asects[addr] = record if not asects and ctx.ntry_record(): @@ -104,8 +115,8 @@ def visitAbs_block(self, ctx: ObjectFileParser.Abs_blockContext): asect.code_locations[byte] = loc return addr, asect - def visitRsect_block(self, ctx: ObjectFileParser.Rsect_blockContext): - name = self.visitName_record(ctx.name_record()) + def visitRsect_block(self, ctx: ObjectFileParser.Rsect_blockContext) -> tuple[str, ObjectSectionRecord]: + name: str = self.visitName_record(ctx.name_record()) if ctx.alig_record(): align = self.visitAlig_record(ctx.alig_record()) else: @@ -126,7 +137,7 @@ def visitRsect_block(self, ctx: ObjectFileParser.Rsect_blockContext): def visitTarg_record(self, ctx: ObjectFileParser.Targ_recordContext): return self.visitLabel(ctx.label()) - def visitSource_record(self, ctx: ObjectFileParser.Source_recordContext): + def visitSource_record(self, ctx: ObjectFileParser.Source_recordContext) -> str: return self.visitFilepath(ctx.filepath()) def visitAbs_record(self, ctx: ObjectFileParser.Abs_recordContext): @@ -134,10 +145,27 @@ def visitAbs_record(self, ctx: ObjectFileParser.Abs_recordContext): data = self.visitData(ctx.data()) return addr, ObjectSectionRecord('$abs', addr, data, {}, [], {}) - def visitLoc_record(self, ctx: ObjectFileParser.Loc_recordContext): - res = {} - for byte, line, col in map(self.visitLocation, ctx.location()): - res[byte] = CodeLocation(None, line, col) + def visitLocations(self, ctx: ObjectFileParser.LocationsContext) -> Iterator[tuple[int, int, int, int]]: + def try_int(value: str) -> int: + try: + return int(value, 16) + except ValueError: + raise ObjectFileException(self.file, ctx.start.line, f'Not a hex number: {value}') + + locations= cast(str, ctx.LOCS().getText()) + for location in locations.strip().split(" "): + parts = location.split(":") + if len(parts) == 3: + yield (0, *map(try_int, parts)) + elif len(parts) == 4: + yield tuple(map(try_int, parts)) + else: + raise ObjectFileException(self.file, ctx.start.line, f'Invalid location: {location}') + + def visitLoc_record(self, ctx: ObjectFileParser.Loc_recordContext) -> dict[int, CodeLocation]: + res: dict[int, CodeLocation] = {} + for index, byte, lin, col in self.visitLocations(ctx.locations()): + res[byte] = CodeLocation(index, lin, col) # unsafe: will be converted later return res def visitNtry_record(self, ctx: ObjectFileParser.Ntry_recordContext): @@ -145,7 +173,7 @@ def visitNtry_record(self, ctx: ObjectFileParser.Ntry_recordContext): address = self.visitNumber(ctx.number()) return label, address - def visitName_record(self, ctx: ObjectFileParser.Name_recordContext): + def visitName_record(self, ctx: ObjectFileParser.Name_recordContext) -> str: return self.visitSection(ctx.section()) def visitAlig_record(self, ctx: ObjectFileParser.Alig_recordContext): @@ -154,7 +182,7 @@ def visitAlig_record(self, ctx: ObjectFileParser.Alig_recordContext): def visitData_record(self, ctx: ObjectFileParser.Data_recordContext): return self.visitData(ctx.data()) - def visitFilepath(self, ctx: ObjectFileParser.FilepathContext): + def visitFilepath(self, ctx: ObjectFileParser.FilepathContext) -> str: return ctx.getText() def visitRel_record(self, ctx: ObjectFileParser.Rel_recordContext): @@ -206,10 +234,6 @@ def visitEntry_usage(self, ctx: ObjectFileParser.Entry_usageContext): def visitRange(self, ctx: ObjectFileParser.RangeContext): return range(self.visitNumber(ctx.number(0)), self.visitNumber(ctx.number(1))) - def visitLocation(self, ctx: ObjectFileParser.LocationContext): - return self.visitNumber(ctx.number(0)), self.visitNumber(ctx.number(1)), \ - self.visitNumber(ctx.number(2)) - def visitLabel(self, ctx: ObjectFileParser.LabelContext): return ctx.getText()