示例#1
0
    def add(self, segment: Segment):
        entries = segment.get_linker_entries()
        self.entries.extend(entries)

        self._begin_segment(segment)

        do_next = False
        for i, entry in enumerate(entries):
            if entry.section == "linker":  # TODO: isinstance is preferable
                self._end_block()
                self._begin_segment(entry.segment)

            start = entry.segment.rom_start
            if isinstance(start, int):
                # Create new sections for non-0x10 alignment (hack)
                if start % 0x10 != 0 and i != 0 or do_next:
                    self._end_block()
                    self._begin_segment(entry.segment)
                    do_next = False

                if start % 0x10 != 0 and i != 0:
                    do_next = True

            path_cname = re.sub(
                r"[^0-9a-zA-Z_]", "_",
                str(entry.segment.dir / entry.segment.name) +
                ".".join(entry.object_path.suffixes[:-1]))
            self._write_symbol(path_cname, ".")

            if entry.section != "linker":
                self._writeln(f"{entry.object_path}({entry.section});")

        self._end_segment(segment)
示例#2
0
    def add(self, segment: Segment):
        entries = segment.get_linker_entries()
        self.entries.extend(entries)

        self._begin_segment(segment)

        seg_name = get_segment_cname(segment)

        self._write_symbol(f"{seg_name}_TEXT_START", ".")

        force_new_section = False
        text_ended = False
        data_started = False
        data_ended = False
        bss_started = False
        cur_section = None

        for i, entry in enumerate(entries):
            cur_section = entry.section

            if cur_section == "linker":  # TODO: isinstance is preferable
                self._end_block()
                self._begin_segment(entry.segment)
                continue
            elif cur_section == "linker_offset":
                self._write_symbol(
                    f"{get_segment_cname(entry.segment)}_OFFSET",
                    f". - {get_segment_cname(segment)}_ROM_START")
                continue

            # text/data/bss START/END labels
            if not data_started and ("data" in cur_section
                                     or "rodata" in cur_section):
                if not text_ended:
                    text_ended = True
                    self._write_symbol(f"{seg_name}_TEXT_END", ".")

                data_started = True
                self._write_symbol(f"{seg_name}_DATA_START", ".")
            elif data_started and not data_ended and "data" not in cur_section and "rodata" not in cur_section:
                data_ended = True
                self._write_symbol(f"{seg_name}_DATA_END", ".")

                if not bss_started and i < (
                        len(entries) - 1) and "bss" in entries[i + 1].section:
                    bss_started = True
                    self._write_symbol(f"{seg_name}_BSS_START", ".")
            elif not bss_started and "bss" in cur_section:
                bss_started = True
                self._write_symbol(f"{seg_name}_BSS_START", ".")

            if options.get("enable_ld_alignment_hack", False):
                start = entry.segment.rom_start
                if isinstance(start, int):
                    # Create new sections for non-subalign alignment (hack)
                    if start % 0x10 != 0 and i != 0 or force_new_section:
                        self._end_block()
                        self._begin_segment(entry.segment, mid_segment=True)
                        force_new_section = False

                    if start % 0x10 != 0 and i != 0:
                        force_new_section = True

            if entry.object_path and cur_section == ".data":
                path_cname = re.sub(
                    r"[^0-9a-zA-Z_]", "_",
                    str(entry.segment.dir / entry.segment.name) +
                    ".".join(entry.object_path.suffixes[:-1]))
                self._write_symbol(path_cname, ".")

            self._writeln(f"{entry.object_path}({cur_section});")

        if not text_ended:
            self._write_symbol(f"{seg_name}_TEXT_END", ".")
        if not data_started:
            self._write_symbol(f"{seg_name}_DATA_START", ".")
        if not data_ended:
            self._write_symbol(f"{seg_name}_DATA_END", ".")
        if not bss_started:
            self._write_symbol(f"{seg_name}_BSS_START", ".")
        self._write_symbol(f"{seg_name}_BSS_END", ".")

        self._end_segment(segment)
示例#3
0
    def add(self, segment: Segment):
        entries = segment.get_linker_entries()
        self.entries.extend(entries)

        self._begin_segment(segment)

        seg_name = get_segment_cname(segment)

        section_labels = [
            LinkerSection(l) for l in options.ld_section_labels()
            if l in options.get_section_order()
        ]

        force_new_section = False
        cur_section = None

        for i, entry in enumerate(entries):
            cur_section = entry.section

            if cur_section == "linker":  # TODO: isinstance is preferable
                self._end_block()
                self._begin_segment(entry.segment)
                continue
            elif cur_section == "linker_offset":
                self._write_symbol(
                    f"{get_segment_cname(entry.segment)}_OFFSET",
                    f". - {get_segment_cname(segment)}_ROM_START",
                )
                continue

            for i, section in enumerate(section_labels):
                if not section.started and section.name == cur_section:
                    if i > 0:
                        if not section_labels[i - 1].ended:
                            section_labels[i - 1].ended = True
                            self._write_symbol(
                                f"{seg_name}{section_labels[i - 1].name.upper()}_END",
                                ".",
                            )
                    section.started = True
                    self._write_symbol(
                        f"{seg_name}{section.name.upper()}_START", ".")

            if options.enable_ld_alignment_hack():
                start = entry.segment.rom_start
                if isinstance(start, int):
                    # Create new sections for non-subalign alignment (hack)
                    if start % 0x10 != 0 and i != 0 or force_new_section:
                        self._end_block()
                        self._begin_segment(entry.segment, mid_segment=True)
                        force_new_section = False

                    if start % 0x10 != 0 and i != 0:
                        force_new_section = True

            if (entry.object_path and cur_section == ".data"
                    and entry.segment.type != "lib"):
                path_cname = re.sub(
                    r"[^0-9a-zA-Z_]",
                    "_",
                    str(entry.segment.dir / entry.segment.name) +
                    ".".join(entry.object_path.suffixes[:-1]),
                )
                self._write_symbol(path_cname, ".")

            # Write out manual entries for images inside .data segments
            seg = entry.segment
            if isinstance(seg, CommonSegData):
                for subseg in seg.subsegments:
                    if isinstance(subseg, N64SegImg):
                        self._write_symbol(get_segment_cname(subseg),
                                           f"0x{subseg.rom_start:X}")

            self._writeln(f"{entry.object_path}({cur_section});")

        for section in section_labels:
            if section.started and not section.ended:
                self._write_symbol(
                    f"{seg_name}_{dotless_type(section.name).upper()}_END",
                    ".")

        self._end_segment(segment)