#!/usr/bin/env bash

# Part of the AVRDUDE project https://github.com/avrdudes/avrdude
# Published under GNU General Public License, version 2 (GPL-2.0)
# Copyright (C) 2007 Johannes Bauer <JohannesBauer@gmx.de>
# Copyright (C) 2024 Small modifications by Stefan Rueger <stefan.rueger@urclocks.com>

progname=$(basename "$0")
for pgm in sort grep awk avr-objdump avr-nm; do
  hash $pgm 2>/dev/null || { echo "$progname: $pgm does not seem to be installed, exiting"; exit 1; }
done

case "$1" in
  "" | -h | --help )
    cat <<END
Syntax: $progname <file>.elf
Function: output a tagfile suitable for the avrdude disasm -t=<tagfile> command
Options: none
END
    exit 1
    ;;
esac

echo "# Automatically generated tagfile via ${progname} ${1}"
avr-objdump -d "$1" | grep '<.*>:' | awk '{
  ADDR = strtonum("0x" $1);
  printf("0x%04x L     %s\n", ADDR, substr($2, 2, length($2) - 3));
}'
echo
avr-nm "$1" | grep '^0080' | sort | grep -Ev '_(_bss_start|_data_end|_data_start|_bss_end|edata|DATA_REGION_ORIGIN)' | awk '
{
  ADDR = strtonum("0x" $1) - strtonum("0x800000");
  if (LAST != "") {
    STARTADDR = LAST;
    ENDADDR = ADDR - 1;
    SYMBOL = LASTSYM;
    SIZE = ENDADDR - STARTADDR + 1;
    if (SIZE == 1) {
      printf("0x%04x M B 1 %s\n", STARTADDR, SYMBOL);
    } else if (SIZE == 2) {
      printf("0x%04x M W 1 %s\n", STARTADDR, SYMBOL);
    } else {
      printf("0x%04x M B %d %s\n", STARTADDR, SIZE, SYMBOL);
    }

  }
  LAST = ADDR;
  LASTSYM = $3;
}'
