From c2da7f58cdd8fe8c1d3c02c2f2442807ca431559 Mon Sep 17 00:00:00 2001 From: soohyuk-cho Date: Wed, 9 Oct 2024 22:19:48 -0700 Subject: [PATCH 1/2] Add scripts for sparse elf generation --- sparsity-testing-scripts/create_mem_bin.py | 19 ++ .../create_mem_regions.py | 218 ++++++++++++++++++ sparsity-testing-scripts/linker_script_gen.py | 83 +++++++ .../memory_region_scanner.cpp | 182 +++++++++++++++ sparsity-testing-scripts/sparse-mem-link.sh | 147 ++++++++++++ 5 files changed, 649 insertions(+) create mode 100644 sparsity-testing-scripts/create_mem_bin.py create mode 100755 sparsity-testing-scripts/create_mem_regions.py create mode 100644 sparsity-testing-scripts/linker_script_gen.py create mode 100644 sparsity-testing-scripts/memory_region_scanner.cpp create mode 100755 sparsity-testing-scripts/sparse-mem-link.sh diff --git a/sparsity-testing-scripts/create_mem_bin.py b/sparsity-testing-scripts/create_mem_bin.py new file mode 100644 index 000000000..cbb1f99bd --- /dev/null +++ b/sparsity-testing-scripts/create_mem_bin.py @@ -0,0 +1,19 @@ +# create_mem_bin.py +import struct + +def create_mem_bin(filename, total_size=0x10000000, pattern=0xDEADBEEF): + with open(filename, 'wb') as f: + # Write first 16 bytes (4 repetitions of 0xDEADBEEF) + for _ in range(4): + f.write(struct.pack(' 0: + write_size = min(chunk_size, remaining) + f.write(zero_chunk[:write_size]) + remaining -= write_size + +if __name__ == '__main__': + create_mem_bin('mem.bin') diff --git a/sparsity-testing-scripts/create_mem_regions.py b/sparsity-testing-scripts/create_mem_regions.py new file mode 100755 index 000000000..b18fe1e36 --- /dev/null +++ b/sparsity-testing-scripts/create_mem_regions.py @@ -0,0 +1,218 @@ +#!/usr/bin/env python3 + +import sys +import struct +import os + +def parse_regions(regions_file): + """ + Parses the regions.txt file and returns a list of tuples containing start addresses and sizes. + """ + regions = [] + with open(regions_file, 'r') as f: + for line in f: + # Skip empty lines and comments + if not line.strip() or line.startswith('#'): + continue + parts = line.strip().split() + if len(parts) != 2: + print(f"Warning: Invalid line format: {line.strip()}") + continue + start_str, size_str = parts + try: + start = int(start_str, 16) + size = int(size_str, 10) + regions.append( (start, size) ) + except ValueError: + print(f"Warning: Invalid hexadecimal number in line: {line.strip()}") + continue + return regions + +def read_elf_header(f): + """ + Reads the ELF header from the file and returns a dictionary with relevant fields. + """ + f.seek(0) + # ELF header for 64-bit little endian + elf_header_struct = struct.Struct('<16sHHIQQQIHHHHHH') + elf_header_data = f.read(elf_header_struct.size) + unpacked = elf_header_struct.unpack(elf_header_data) + + elf_header = { + 'e_ident': unpacked[0], + 'e_type': unpacked[1], + 'e_machine': unpacked[2], + 'e_version': unpacked[3], + 'e_entry': unpacked[4], + 'e_phoff': unpacked[5], + 'e_shoff': unpacked[6], + 'e_flags': unpacked[7], + 'e_ehsize': unpacked[8], + 'e_phentsize': unpacked[9], + 'e_phnum': unpacked[10], + 'e_shentsize': unpacked[11], + 'e_shnum': unpacked[12], + 'e_shstrndx': unpacked[13], + } + return elf_header + +def read_program_headers(f, elf_header): + """ + Reads all program headers and returns a list of dictionaries. + """ + program_headers = [] + f.seek(elf_header['e_phoff']) + ph_struct = struct.Struct('= end_va: + continue + # Calculate overlap + overlap_start = max(start_va, seg_start) + overlap_end = min(end_va, seg_end) + overlap_size = overlap_end - overlap_start + # Calculate file offset + offset = ph['p_offset'] + (overlap_start - ph['p_vaddr']) + # Read the data + f.seek(offset) + chunk = f.read(overlap_size) + if len(chunk) < overlap_size: + print(f"Warning: Could not read enough data for VA 0x{overlap_start:X}") + chunk += b'\x00' * (overlap_size - len(chunk)) + # Calculate where to place the data in the region + region_offset = overlap_start - start_va + # Ensure data array is big enough + while len(data) < region_offset: + data += b'\x00' + # Insert data_chunk at the correct offset + if len(data) < region_offset + overlap_size: + data += b'\x00' * (region_offset + overlap_size - len(data)) + data[region_offset:region_offset + overlap_size] = chunk + # After processing all segments, ensure data is exactly 'size' bytes + if len(data) < size: + data += b'\x00' * (size - len(data)) + elif len(data) > size: + data = data[:size] + return data + +def create_binary_file(data, output_bin): + """ + Writes the binary data to 'output_bin'. + """ + with open(output_bin, 'wb') as f: + f.write(data) + +def create_assembly_file(symbol_name, section_name, data_bin, output_asm): + """ + Creates an assembly file that defines a section containing the binary data. + """ + with open(output_asm, 'w') as f: + f.write(f"/* {output_asm} - Auto-generated Assembly File */\n\n") + f.write(f" .section {section_name}, \"aw\", @progbits\n") + f.write(f" .global {symbol_name}\n") + f.write(f"{symbol_name}:\n") + f.write(f" .incbin \"{data_bin}\"\n\n") + +def assemble_section(asm_file, obj_file): + """ + Assembles the assembly file into an object file using the RISC-V assembler. + """ + import subprocess + cmd = ['riscv64-unknown-elf-as', '-o', obj_file, asm_file] + try: + subprocess.check_call(cmd) + except subprocess.CalledProcessError as e: + print(f"Error: Assembly failed for {asm_file}: {e}") + sys.exit(1) + +def main(): + if len(sys.argv) != 3: + print("Usage: python3 extract_regions.py ") + sys.exit(1) + + mem_elf = sys.argv[1] + regions_file = sys.argv[2] + + # Check if mem.elf exists + if not os.path.isfile(mem_elf): + print(f"Error: File '{mem_elf}' does not exist.") + sys.exit(1) + + # Check if regions.txt exists + if not os.path.isfile(regions_file): + print(f"Error: File '{regions_file}' does not exist.") + sys.exit(1) + + regions = parse_regions(regions_file) + if not regions: + print("Error: No valid regions found in regions.txt.") + sys.exit(1) + + # Open mem.elf + with open(mem_elf, 'rb') as f: + elf_header = read_elf_header(f) + # Verify ELF Magic Number + if elf_header['e_ident'][:4] != b'\x7fELF': + print("Error: Not a valid ELF file.") + sys.exit(1) + # Verify 64-bit ELF + if elf_header['e_ident'][4] != 2: + print("Error: Only 64-bit ELF files are supported.") + sys.exit(1) + # Parse program headers + program_headers = read_program_headers(f, elf_header) + + for idx, (start, size) in enumerate(regions): + print(f"Processing region {idx}: Start=0x{start:X}, Size=0x{size:X}") + data = extract_data(f, program_headers, start, size) + + # Create binary file + data_bin = f"data_mem{idx}.bin" + create_binary_file(data, data_bin) + print(f" Created binary file: {data_bin}") + + # Create assembly file + section_name = f".data_mem{idx}" + symbol_name = f"data_mem{idx}" # Changed symbol name to avoid leading '.' + asm_file = f"data_mem{idx}.S" + create_assembly_file(symbol_name, section_name, data_bin, asm_file) + print(f" Created assembly file: {asm_file}") + + # Assemble into .o file + obj_file = f"data_mem{idx}.o" + assemble_section(asm_file, obj_file) + print(f" Assembled object file: {obj_file}") + + print("All memory regions processed successfully.") + +if __name__ == "__main__": + main() diff --git a/sparsity-testing-scripts/linker_script_gen.py b/sparsity-testing-scripts/linker_script_gen.py new file mode 100644 index 000000000..2e499e19b --- /dev/null +++ b/sparsity-testing-scripts/linker_script_gen.py @@ -0,0 +1,83 @@ +#!/usr/bin/env python3 + +# generate_linker_script.py + +import sys + +def generate_linker_script(regions, output_filename): + with open(output_filename, 'w') as f: + f.write("/* sparse_mem.ld - Auto-generated Linker Script */\n\n") + + # Define a single MEMORY region + f.write("MEMORY\n") + f.write("{\n") + f.write(" MEM (rwx) : ORIGIN = 0x80000000, LENGTH = 0x80000000\n") + f.write("}\n\n") + + # Define SECTIONS with specified origin addresses + f.write("SECTIONS\n") + f.write("{\n") + for idx, (start, size, mem_region) in enumerate(regions): + section_name = f".data_mem{idx}" + f.write(f" {section_name} 0x{start:X} :\n") + f.write(" {\n") + f.write(f" KEEP(*({section_name}))\n") + f.write(" } > ") + f.write(f"{mem_region}\n\n") + + # Standard sections + f.write(" .text :\n") + f.write(" {\n") + f.write(" *(.text)\n") + f.write(" } > MEM\n\n") + + f.write(" .bss :\n") + f.write(" {\n") + f.write(" *(.bss)\n") + f.write(" *(COMMON)\n") + f.write(" } > MEM\n\n") + + f.write(" /* Additional sections can be defined here */\n") + f.write("}\n") + +def parse_regions_with_memory(regions_file): + """ + Parses regions.txt and assigns each region to the single MEMORY region MEM. + Assumes regions.txt has lines with: start_address size + Sizes are specified in decimal. + """ + regions = [] + with open(regions_file, 'r') as rf: + for line in rf: + parts = line.strip().split() + if len(parts) != 2: + continue + start_str, size_str = parts + try: + start = int(start_str, 16) # Start address in hexadecimal + size = int(size_str, 10) # Size in decimal + mem_region = "MEM" # Single memory region + regions.append( (start, size, mem_region) ) + except ValueError: + print(f"Warning: Invalid number format in line: {line.strip()}") + continue + return regions + +def main(): + if len(sys.argv) != 3: + print("Usage: python3 generate_linker_script.py ") + sys.exit(1) + + regions_file = sys.argv[1] + output_ld_file = sys.argv[2] + + regions = parse_regions_with_memory(regions_file) + if not regions: + print("Error: No valid regions found in regions.txt.") + sys.exit(1) + + generate_linker_script(regions, output_ld_file) + print(f"Linker script '{output_ld_file}' generated successfully.") + +if __name__ == "__main__": + main() diff --git a/sparsity-testing-scripts/memory_region_scanner.cpp b/sparsity-testing-scripts/memory_region_scanner.cpp new file mode 100644 index 000000000..64b3c8739 --- /dev/null +++ b/sparsity-testing-scripts/memory_region_scanner.cpp @@ -0,0 +1,182 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct MemoryRegion { + Elf64_Addr start_addr; + Elf64_Xword size; +}; + +void usage(const char *progname) { + std::cerr << "Usage: " << progname << " " << std::endl; +} + +int scan_memory_regions(const char *input_file, size_t chunk_size, const char *output_file) { + if (elf_version(EV_CURRENT) == EV_NONE) { + std::cerr << "ELF library initialization failed: " << elf_errmsg(-1) << std::endl; + return 1; + } + + int fd_in = open(input_file, O_RDONLY); + if (fd_in < 0) { + perror("Failed to open input file"); + return 1; + } + + Elf *e_in = elf_begin(fd_in, ELF_C_READ, nullptr); + if (!e_in) { + std::cerr << "elf_begin() failed: " << elf_errmsg(-1) << std::endl; + close(fd_in); + return 1; + } + + GElf_Ehdr ehdr; + if (gelf_getehdr(e_in, &ehdr) != &ehdr) { + std::cerr << "Failed to get ELF header: " << elf_errmsg(-1) << std::endl; + elf_end(e_in); + close(fd_in); + return 1; + } + + // SOOHYUK: Debug: Print ELF header information + std::cout << "ELF Class: " << ((gelf_getclass(e_in) == ELFCLASS32) ? "32-bit" : "64-bit") << std::endl; + std::cout << "ELF Data Encoding: " << ((ehdr.e_ident[EI_DATA] == ELFDATA2LSB) ? "Little Endian" : "Big Endian") << std::endl; + + // Retrieve the number of program headers + size_t n_phdrs; + if (elf_getphdrnum(e_in, &n_phdrs) != 0) { + std::cerr << "Failed to get program header count: " << elf_errmsg(-1) << std::endl; + elf_end(e_in); + close(fd_in); + return 1; + } + + std::vector useful_regions; + + // Iterate over each program header + for (size_t i = 0; i < n_phdrs; ++i) { + GElf_Phdr phdr; + if (gelf_getphdr(e_in, i, &phdr) != &phdr) { + std::cerr << "Failed to get program header: " << elf_errmsg(-1) << std::endl; + elf_end(e_in); + close(fd_in); + return 1; + } + + // SOOHYUK: Debug: Print program header information + std::cout << "\nProcessing Segment " << i << ":" << std::endl; + std::cout << " Type: " << phdr.p_type << std::endl; + std::cout << " Offset: 0x" << std::hex << phdr.p_offset << std::dec << std::endl; + std::cout << " Virtual Address: 0x" << std::hex << phdr.p_vaddr << std::dec << std::endl; + std::cout << " Physical Address: 0x" << std::hex << phdr.p_paddr << std::dec << std::endl; + std::cout << " File Size: " << phdr.p_filesz << " bytes" << std::endl; + std::cout << " Memory Size: " << phdr.p_memsz << " bytes" << std::endl; + std::cout << " Flags: " << phdr.p_flags << std::endl; + + if (phdr.p_type != PT_LOAD) { + std::cout << " Skipping non-loadable segment." << std::endl; + continue; + } + + // SOOHYUK: Debug: Print virtual address and size (to accomodate memory concatenations) + std::cout << " Segment Virtual Address: 0x" << std::hex << phdr.p_vaddr << std::dec << std::endl; + std::cout << " Segment Size (filesz): " << phdr.p_filesz << " bytes" << std::endl; + + // Seek to the segment's file offset + if (lseek(fd_in, phdr.p_offset, SEEK_SET) < 0) { + perror("Failed to seek in input file"); + elf_end(e_in); + close(fd_in); + return 1; + } + + // Read the segment's data + std::vector segment_data(phdr.p_filesz); + ssize_t bytes_read = read(fd_in, segment_data.data(), phdr.p_filesz); + if (bytes_read != static_cast(phdr.p_filesz)) { + perror("Failed to read segment data"); + std::cerr << "Expected: " << phdr.p_filesz << ", Read: " << bytes_read << std::endl; + elf_end(e_in); + close(fd_in); + return 1; + } + + // Calculate the number of chunks in this segment + size_t num_chunks = (phdr.p_filesz + chunk_size - 1) / chunk_size; + + for (size_t chunk_idx = 0; chunk_idx < num_chunks; ++chunk_idx) { + size_t chunk_offset = chunk_idx * chunk_size; + size_t chunk_end = std::min(chunk_offset + chunk_size, static_cast(phdr.p_filesz)); + size_t actual_chunk_size = chunk_end - chunk_offset; + + // Check if the chunk is all zeros + bool all_zero = std::all_of(segment_data.begin() + chunk_offset, segment_data.begin() + chunk_end, + [](unsigned char c) { return c == 0; }); + + // Compute the absolute start address + Elf64_Addr absolute_start_addr = phdr.p_vaddr + chunk_offset; + + // Debug: Print chunk information + std::cout << " Chunk " << chunk_idx << ": " + << "Offset " << std::hex << chunk_offset + << ", Size " << std::dec << actual_chunk_size + << ", Absolute Start Address: 0x" << std::hex << absolute_start_addr + << ", All Zero: " << (all_zero ? "Yes" : "No") << std::dec << std::endl; + + if (!all_zero) { + // Record the useful memory region + MemoryRegion region; + region.start_addr = absolute_start_addr; + region.size = actual_chunk_size; + useful_regions.push_back(region); + } + } + } + + // Clean up ELF resources + elf_end(e_in); + close(fd_in); + + // Sort the useful regions by starting address for clarity + std::sort(useful_regions.begin(), useful_regions.end(), + [](const MemoryRegion &a, const MemoryRegion &b) -> bool { + return a.start_addr < b.start_addr; + }); + + // Output the useful memory regions to the output file + std::ofstream ofs(output_file); + if (!ofs) { + std::cerr << "Failed to open output file: " << output_file << std::endl; + return 1; + } + + for (const auto ®ion : useful_regions) { + ofs << "0x" << std::hex << region.start_addr << " " << std::dec << region.size << std::endl; + } + + ofs.close(); + + std::cout << "\nScan complete. Useful memory regions written to: " << output_file << std::endl; + return 0; +} + +int main(int argc, char **argv) { + if (argc != 4) { + usage(argv[0]); + return 1; + } + const char *input_elf = argv[1]; + size_t chunk_size = std::stoul(argv[2]); + const char *output_file = argv[3]; + + return scan_memory_regions(input_elf, chunk_size, output_file); +} diff --git a/sparsity-testing-scripts/sparse-mem-link.sh b/sparsity-testing-scripts/sparse-mem-link.sh new file mode 100755 index 000000000..9124152dc --- /dev/null +++ b/sparsity-testing-scripts/sparse-mem-link.sh @@ -0,0 +1,147 @@ +#!/bin/bash + +# set -e + +# usage() { +# echo "Usage: $0 [OPTIONS]" +# echo "" +# echo "Options" +# echo " --help -h : Display this message" +# echo " -n : Number of harts" +# echo " -b : Binary to run in spike" +# echo " -p : PC to take checkpoint at [default 0x80000000]" +# echo " -i : Instructions after PC to take checkpoint at [default 0]" +# echo " -m : ISA to pass to spike for checkpoint generation [default rv64gc]" +# echo " -o : Output directory to store the checkpoint in. [default ...loadarch]" +# exit "$1" +# } + +# NHARTS=1 +BINARY="hello.riscv.0x80000000.1000.loadarch/mem.elf" +# PC="0x80000000" +# INSNS=0 +# ISA="rv64gc" +# OUTPATH="" +# while [ "$1" != "" ]; +# do +# case $1 in +# -h | --help ) +# usage 3 ;; +# -n ) +# shift +# NHARTS=$1 ;; +# -b ) +# shift +# BINARY=$1 ;; +# -p ) +# shift +# PC=$1 ;; +# -i ) +# shift +# INSNS=$1 ;; +# -m ) +# shift +# ISA=$1 ;; +# -o ) +# shift +# OUTPATH=$1 ;; +# * ) +# error "Invalid option $1" +# usage 1 ;; +# esac +# shift +# done + +# BASEMEM="$((0x80000000)):$((0x10000000))" +# # SooHyuk: change thisBASEMEM="$((0x80000000)):$((0x20000000))" + +# SPIKEFLAGS="-p$NHARTS --pmpregions=0 --isa=$ISA -m$BASEMEM" +# BASENAME=$(basename -- $BINARY) + +# if [ -z "$OUTPATH" ] ; then +# OUTPATH=$BASENAME.$PC.$INSNS.loadarch +# fi + +# echo "Generating loadarch directory $OUTPATH" +# rm -rf $OUTPATH +# mkdir -p $OUTPATH + +# LOADARCH_FILE=$OUTPATH/loadarch +# RAWMEM_ELF=$OUTPATH/raw.elf +# LOADMEM_ELF=$OUTPATH/mem.elf +# CMDS_FILE=$OUTPATH/cmds_tmp.txt +# SPIKECMD_FILE=$OUTPATH/spikecmd.sh + +# echo "Generating state capture spike interactive commands in $CMDS_FILE" +# echo "until pc 0 $PC" >> $CMDS_FILE +# echo "rs $INSNS" >> $CMDS_FILE +# echo "dump" >> $CMDS_FILE +# for (( h=0; h<$NHARTS; h++ )) +# do +# echo "pc $h" >> $CMDS_FILE +# echo "priv $h" >> $CMDS_FILE +# echo "reg $h fcsr" >> $CMDS_FILE + +# echo "reg $h vstart" >> $CMDS_FILE +# echo "reg $h vxsat" >> $CMDS_FILE +# echo "reg $h vxrm" >> $CMDS_FILE +# echo "reg $h vcsr" >> $CMDS_FILE +# echo "reg $h vtype" >> $CMDS_FILE + +# echo "reg $h stvec" >> $CMDS_FILE +# echo "reg $h sscratch" >> $CMDS_FILE +# echo "reg $h sepc" >> $CMDS_FILE +# echo "reg $h scause" >> $CMDS_FILE +# echo "reg $h stval" >> $CMDS_FILE +# echo "reg $h satp" >> $CMDS_FILE + +# echo "reg $h mstatus" >> $CMDS_FILE +# echo "reg $h medeleg" >> $CMDS_FILE +# echo "reg $h mideleg" >> $CMDS_FILE +# echo "reg $h mie" >> $CMDS_FILE +# echo "reg $h mtvec" >> $CMDS_FILE +# echo "reg $h mscratch" >> $CMDS_FILE +# echo "reg $h mepc" >> $CMDS_FILE +# echo "reg $h mcause" >> $CMDS_FILE +# echo "reg $h mtval" >> $CMDS_FILE +# echo "reg $h mip" >> $CMDS_FILE + +# echo "reg $h mcycle" >> $CMDS_FILE +# echo "reg $h minstret" >> $CMDS_FILE + +# echo "mtime" >> $CMDS_FILE +# echo "mtimecmp $h" >> $CMDS_FILE + +# for (( fr=0; fr<32; fr++ )) +# do +# echo "freg $h $fr" >> $CMDS_FILE +# done +# for (( xr=0; xr<32; xr++ )) +# do +# echo "reg $h $xr" >> $CMDS_FILE +# done +# echo "vreg $h" >> $CMDS_FILE +# done +# echo "quit" >> $CMDS_FILE + +# echo "spike -d --debug-cmd=$CMDS_FILE $SPIKEFLAGS $BINARY" > $SPIKECMD_FILE + +# echo "Capturing state at checkpoint to spikeout" +# spike -d --debug-cmd=$CMDS_FILE $SPIKEFLAGS $BINARY 2> $LOADARCH_FILE + + +echo "Finding tohost/fromhost in elf file" +TOHOST=$(riscv64-unknown-elf-nm $BINARY | grep tohost | head -c 16) +FROMHOST=$(riscv64-unknown-elf-nm $BINARY | grep fromhost | head -c 16) + +# echo "Compiling memory to elf" +# riscv64-unknown-elf-objcopy -I binary -O elf64-littleriscv mem.0x80000000.bin $RAWMEM_ELF +# rm -rf mem.0x80000000.bin + +echo "Link mem elf files with tohost/fromhost" +# riscv64-unknown-elf-ld -T linker_temp.ld --defsym tohost=0x$TOHOST --defsym fromhost=0x$FROMHOST -o mem_combined.elf mem.0x80000000.o mem.0xA0000000.o +# riscv64-unknown-elf-ld -T linker_temp.ld --defsym tohost=0x$TOHOST --defsym fromhost=0x$FROMHOST -o final_program_hosts_linked.elf final_program.elf +riscv64-unknown-elf-ld -T sparse_mem.ld --defsym tohost=0x$TOHOST --defsym fromhost=0x$FROMHOST -o final_program.elf data_mem0.o data_mem1.o data_mem2.o data_mem3.o data_mem4.o data_mem5.o data_mem6.o data_mem7.o data_mem8.o data_mem9.o data_mem10.o +# riscv64-unknown-elf-ld -Tdata=0x80000000 -nmagic --defsym tohost=0x$TOHOST --defsym fromhost=0x$FROMHOST -o $LOADMEM_ELF $RAWMEM_ELF +# rm -rf $RAWMEM_ELF + From 7626cb5ae1ce7c4463eb127659dbabe6803f4ecf Mon Sep 17 00:00:00 2001 From: soohyuk-cho Date: Wed, 23 Oct 2024 14:12:24 -0700 Subject: [PATCH 2/2] Top level sparse elf generation script added --- software/firemarshal | 2 +- .../create_mem_regions.py | 8 +- sparsity-testing-scripts/final_out_mem.elf | Bin 0 -> 18272 bytes sparsity-testing-scripts/final_program.elf | Bin 0 -> 18272 bytes .../generate_sparse_elf.sh | 138 ++++++++++++++++++ sparsity-testing-scripts/linker_script_gen.py | 0 .../memory_region_scanner.cpp | 35 ++--- 7 files changed, 161 insertions(+), 22 deletions(-) create mode 100755 sparsity-testing-scripts/final_out_mem.elf create mode 100755 sparsity-testing-scripts/final_program.elf create mode 100755 sparsity-testing-scripts/generate_sparse_elf.sh mode change 100644 => 100755 sparsity-testing-scripts/linker_script_gen.py diff --git a/software/firemarshal b/software/firemarshal index 21119e5ce..2cf357b23 160000 --- a/software/firemarshal +++ b/software/firemarshal @@ -1 +1 @@ -Subproject commit 21119e5ce922ff9302f0bc9d2d7349c77f7ac064 +Subproject commit 2cf357b238d86d0f1fca752012366dac7e34994a diff --git a/sparsity-testing-scripts/create_mem_regions.py b/sparsity-testing-scripts/create_mem_regions.py index b18fe1e36..86ea5e522 100755 --- a/sparsity-testing-scripts/create_mem_regions.py +++ b/sparsity-testing-scripts/create_mem_regions.py @@ -192,25 +192,25 @@ def main(): program_headers = read_program_headers(f, elf_header) for idx, (start, size) in enumerate(regions): - print(f"Processing region {idx}: Start=0x{start:X}, Size=0x{size:X}") + # print(f"Processing region {idx}: Start=0x{start:X}, Size=0x{size:X}") data = extract_data(f, program_headers, start, size) # Create binary file data_bin = f"data_mem{idx}.bin" create_binary_file(data, data_bin) - print(f" Created binary file: {data_bin}") + # print(f" Created binary file: {data_bin}") # Create assembly file section_name = f".data_mem{idx}" symbol_name = f"data_mem{idx}" # Changed symbol name to avoid leading '.' asm_file = f"data_mem{idx}.S" create_assembly_file(symbol_name, section_name, data_bin, asm_file) - print(f" Created assembly file: {asm_file}") + # print(f" Created assembly file: {asm_file}") # Assemble into .o file obj_file = f"data_mem{idx}.o" assemble_section(asm_file, obj_file) - print(f" Assembled object file: {obj_file}") + # print(f" Assembled object file: {obj_file}") print("All memory regions processed successfully.") diff --git a/sparsity-testing-scripts/final_out_mem.elf b/sparsity-testing-scripts/final_out_mem.elf new file mode 100755 index 0000000000000000000000000000000000000000..7d83a0da9b824c78eb58647d902c2d1353607337 GIT binary patch literal 18272 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 A9{>OV literal 0 HcmV?d00001 diff --git a/sparsity-testing-scripts/final_program.elf b/sparsity-testing-scripts/final_program.elf new file mode 100755 index 0000000000000000000000000000000000000000..7d83a0da9b824c78eb58647d902c2d1353607337 GIT binary patch literal 18272 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 A9{>OV literal 0 HcmV?d00001 diff --git a/sparsity-testing-scripts/generate_sparse_elf.sh b/sparsity-testing-scripts/generate_sparse_elf.sh new file mode 100755 index 000000000..7db3601cb --- /dev/null +++ b/sparsity-testing-scripts/generate_sparse_elf.sh @@ -0,0 +1,138 @@ +#!/bin/bash + +# generate_sparse_elf.sh + +# Description: +# This script takes an input ELF file and generates a final sparse ELF file. +# It automates the scanning of memory regions, generation of the linker script, +# extraction of data sections, assembly, and linking, including handling +# 'tohost' and 'fromhost' symbols. + +# Usage: +# ./generate_sparse_elf.sh + +# Check for correct number of arguments +if [ "$#" -ne 2 ]; then + echo "Usage: $0 " + exit 1 +fi + +# Input and output ELF files +INPUT_ELF="$1" +OUTPUT_ELF="$2" + +# Temporary and intermediate files directory +WORK_DIR="sparse_elf_workdir" +mkdir -p "$WORK_DIR" + +# Paths to scripts (assuming they are in the same directory) +SCRIPT_DIR="$(dirname "$0")" +EXTRACT_REGIONS_SCRIPT="$SCRIPT_DIR/create_mem_regions.py" +GENERATE_LINKER_SCRIPT="$SCRIPT_DIR/linker_script_gen.py" +MEMORY_SCANNER_CPP="$SCRIPT_DIR/memory_region_scanner.cpp" +MEMORY_SCANNER_EXEC="$WORK_DIR/memory_region_scanner" +LINKER_SCRIPT="$WORK_DIR/sparse_mem.ld" +REGIONS_FILE="$WORK_DIR/regions.txt" + +# Toolchain prefix (adjust if necessary) +RISCV_PREFIX="riscv64-unknown-elf-" +AS="${RISCV_PREFIX}as" +LD="${RISCV_PREFIX}ld" +NM="${RISCV_PREFIX}nm" +OBJCOPY="${RISCV_PREFIX}objcopy" + +# Step 1: Compile the memory region scanner +echo "Compiling memory region scanner..." +g++ -o "$MEMORY_SCANNER_EXEC" "$MEMORY_SCANNER_CPP" -lelf +if [ $? -ne 0 ]; then + echo "Error: Failed to compile memory_region_scanner.cpp" + exit 1 +fi + +# Step 2: Scan the input ELF file to generate regions.txt +echo "Scanning $INPUT_ELF to generate memory regions..." +CHUNK_SIZE=1024 # Adjust chunk size as needed +"$MEMORY_SCANNER_EXEC" "$INPUT_ELF" "$CHUNK_SIZE" "$REGIONS_FILE" +if [ $? -ne 0 ]; then + echo "Error: Failed to scan memory regions." + exit 1 +fi + +echo "Memory regions written to $REGIONS_FILE" + +# Step 3: Generate the linker script +echo "Generating linker script..." +python3 "$GENERATE_LINKER_SCRIPT" "$REGIONS_FILE" "$LINKER_SCRIPT" +if [ $? -ne 0 ]; then + echo "Error: Failed to generate linker script." + exit 1 +fi + +# Step 4: Extract data sections and create assembly files +echo "Extracting data sections and creating assembly files..." +python3 "$EXTRACT_REGIONS_SCRIPT" "$INPUT_ELF" "$REGIONS_FILE" +if [ $? -ne 0 ]; then + echo "Error: Failed to extract data sections." + exit 1 +fi + +# Step 5: Assemble the assembly files into object files +echo "Assembling data section assembly files..." + +# Collect all .S files +ASM_FILES=(data_mem*.S) + +for ASM_FILE in "${ASM_FILES[@]}"; do + OBJ_FILE="${ASM_FILE%.S}.o" + "$AS" -o "$OBJ_FILE" "$ASM_FILE" + if [ $? -ne 0 ]; then + echo "Error: Assembly failed for $ASM_FILE" + exit 1 + fi +done + +# Move generated files to work directory +mv data_mem*.bin data_mem*.S data_mem*.o "$WORK_DIR/" + +# Step 6: Find 'tohost' and 'fromhost' symbols in the input ELF +echo "Finding 'tohost' and 'fromhost' symbols in $INPUT_ELF..." +TOHOST_ADDR=$("$NM" "$INPUT_ELF" | grep " tohost$" | awk '{print $1}') +FROMHOST_ADDR=$("$NM" "$INPUT_ELF" | grep " fromhost$" | awk '{print $1}') + +if [ -z "$TOHOST_ADDR" ] || [ -z "$FROMHOST_ADDR" ]; then + echo "Error: 'tohost' or 'fromhost' symbols not found in $INPUT_ELF" + exit 1 +fi + +echo "tohost address: 0x$TOHOST_ADDR" +echo "fromhost address: 0x$FROMHOST_ADDR" + +# Step 7: Link all object files into the final ELF +echo "Linking object files to create $OUTPUT_ELF..." + +# Collect all object files +OBJ_FILES=("$WORK_DIR"/data_mem*.o) + +# Build the linker command +LINKER_CMD=("$LD" -T "$LINKER_SCRIPT" "--defsym" "tohost=0x$TOHOST_ADDR" "--defsym" "fromhost=0x$FROMHOST_ADDR" -o "$OUTPUT_ELF") +LINKER_CMD+=("${OBJ_FILES[@]}") + +# Optionally include the main program object file if needed +# If you have a main.o, include it here: +# MAIN_OBJ="main.o" +# LINKER_CMD+=("$MAIN_OBJ") + +# Run the linker command +"${LINKER_CMD[@]}" +if [ $? -ne 0 ]; then + echo "Error: Linking failed." + exit 1 +fi + +echo "Final sparse ELF file created: $OUTPUT_ELF" + +# Optional: Clean up the work directory +# Uncomment the following line if you want to remove intermediate files +# rm -rf "$WORK_DIR" + +exit 0 diff --git a/sparsity-testing-scripts/linker_script_gen.py b/sparsity-testing-scripts/linker_script_gen.py old mode 100644 new mode 100755 diff --git a/sparsity-testing-scripts/memory_region_scanner.cpp b/sparsity-testing-scripts/memory_region_scanner.cpp index 64b3c8739..ba5ac9850 100644 --- a/sparsity-testing-scripts/memory_region_scanner.cpp +++ b/sparsity-testing-scripts/memory_region_scanner.cpp @@ -73,23 +73,23 @@ int scan_memory_regions(const char *input_file, size_t chunk_size, const char *o } // SOOHYUK: Debug: Print program header information - std::cout << "\nProcessing Segment " << i << ":" << std::endl; - std::cout << " Type: " << phdr.p_type << std::endl; - std::cout << " Offset: 0x" << std::hex << phdr.p_offset << std::dec << std::endl; - std::cout << " Virtual Address: 0x" << std::hex << phdr.p_vaddr << std::dec << std::endl; - std::cout << " Physical Address: 0x" << std::hex << phdr.p_paddr << std::dec << std::endl; - std::cout << " File Size: " << phdr.p_filesz << " bytes" << std::endl; - std::cout << " Memory Size: " << phdr.p_memsz << " bytes" << std::endl; - std::cout << " Flags: " << phdr.p_flags << std::endl; + // std::cout << "\nProcessing Segment " << i << ":" << std::endl; + // std::cout << " Type: " << phdr.p_type << std::endl; + // std::cout << " Offset: 0x" << std::hex << phdr.p_offset << std::dec << std::endl; + // std::cout << " Virtual Address: 0x" << std::hex << phdr.p_vaddr << std::dec << std::endl; + // std::cout << " Physical Address: 0x" << std::hex << phdr.p_paddr << std::dec << std::endl; + // std::cout << " File Size: " << phdr.p_filesz << " bytes" << std::endl; + // std::cout << " Memory Size: " << phdr.p_memsz << " bytes" << std::endl; + // std::cout << " Flags: " << phdr.p_flags << std::endl; if (phdr.p_type != PT_LOAD) { - std::cout << " Skipping non-loadable segment." << std::endl; + // std::cout << " Skipping non-loadable segment." << std::endl; continue; } // SOOHYUK: Debug: Print virtual address and size (to accomodate memory concatenations) - std::cout << " Segment Virtual Address: 0x" << std::hex << phdr.p_vaddr << std::dec << std::endl; - std::cout << " Segment Size (filesz): " << phdr.p_filesz << " bytes" << std::endl; + // std::cout << " Segment Virtual Address: 0x" << std::hex << phdr.p_vaddr << std::dec << std::endl; + // std::cout << " Segment Size (filesz): " << phdr.p_filesz << " bytes" << std::endl; // Seek to the segment's file offset if (lseek(fd_in, phdr.p_offset, SEEK_SET) < 0) { @@ -126,11 +126,11 @@ int scan_memory_regions(const char *input_file, size_t chunk_size, const char *o Elf64_Addr absolute_start_addr = phdr.p_vaddr + chunk_offset; // Debug: Print chunk information - std::cout << " Chunk " << chunk_idx << ": " - << "Offset " << std::hex << chunk_offset - << ", Size " << std::dec << actual_chunk_size - << ", Absolute Start Address: 0x" << std::hex << absolute_start_addr - << ", All Zero: " << (all_zero ? "Yes" : "No") << std::dec << std::endl; + // std::cout << " Chunk " << chunk_idx << ": " + // << "Offset " << std::hex << chunk_offset + // << ", Size " << std::dec << actual_chunk_size + // << ", Absolute Start Address: 0x" << std::hex << absolute_start_addr + // << ", All Zero: " << (all_zero ? "Yes" : "No") << std::dec << std::endl; if (!all_zero) { // Record the useful memory region @@ -165,7 +165,8 @@ int scan_memory_regions(const char *input_file, size_t chunk_size, const char *o ofs.close(); - std::cout << "\nScan complete. Useful memory regions written to: " << output_file << std::endl; + std::cout << "\nELF file scan complete." << std::endl; + // std::cout << "\nScan complete. Useful memory regions written to: " << output_file << std::endl; return 0; }