mkoffsets.sh 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. # automatically compute structure offsets for gcc targets in ELF format
  2. # (C) 2018 Kai-Uwe Bloem. This work is placed in the public domain.
  3. #
  4. # usage: mkoffsets <output dir>
  5. CC=${CC:-gcc}
  6. # endianess of target (automagically determined below)
  7. ENDIAN=
  8. # don't do this if ELF format isn't used. it doesn't matter since offsets are
  9. # only needed for the asm parts (currently mips/arm32) and those have ELF
  10. check_elf ()
  11. {
  12. echo '#include <stdint.h>' >/tmp/getoffs.c
  13. echo "const int32_t val = 1;" >>/tmp/getoffs.c
  14. $CC $CFLAGS -I .. -c /tmp/getoffs.c -o /tmp/getoffs.o || exit 1
  15. if ! command -v readelf >/dev/null || ! file /tmp/getoffs.o | grep -q ELF; then
  16. echo "/* mkoffset.sh: no readelf or not ELF, offset table not created */" >$fn
  17. echo "WARNING: no readelf or not ELF, offset table not created"
  18. exit
  19. fi
  20. }
  21. # compile with target C compiler and extract value from .rodata section
  22. compile_rodata ()
  23. {
  24. $CC $CFLAGS -I .. -c /tmp/getoffs.c -o /tmp/getoffs.o || exit 1
  25. # find the name of the .rodata section (in case -fdata-sections is used)
  26. rosect=$(readelf -S /tmp/getoffs.o | grep '\.rodata\|\.sdata' |
  27. sed 's/^[^.]*././;s/ .*//')
  28. # read out .rodata section as hex string (should be only 4 bytes)
  29. ro=$(readelf -x $rosect /tmp/getoffs.o | grep '0x' | cut -c14-48 |
  30. tr -d ' \n' | cut -c1-8)
  31. if [ "$ENDIAN" = "le" ]; then
  32. # swap needed for le target
  33. hex=""
  34. for b in $(echo $ro | sed 's/\([0-9a-f]\{2\}\)/\1 /g'); do
  35. hex=$b$hex;
  36. done
  37. else
  38. hex=$ro
  39. fi
  40. # extract decimal value from hex string
  41. rodata=$(printf "%d" 0x$hex)
  42. }
  43. # determine member offset and create #define
  44. get_define () # prefix struct member member...
  45. {
  46. prefix=$1; shift
  47. struct=$1; shift
  48. field=$(echo $* | sed 's/ /./g')
  49. name=$(echo $* | sed 's/ /_/g')
  50. echo '#include <stdint.h>' > /tmp/getoffs.c
  51. echo '#include "pico/pico_int.h"' >> /tmp/getoffs.c
  52. echo "static const struct $struct p;" >> /tmp/getoffs.c
  53. echo "const int32_t val = (char *)&p.$field - (char*)&p;" >>/tmp/getoffs.c
  54. compile_rodata
  55. line=$(printf "#define %-20s 0x%04x" $prefix$name $rodata)
  56. }
  57. fn="${1:-.}/pico_int_offs.h"
  58. if echo $CFLAGS | grep -qe -flto; then CFLAGS="$CFLAGS -fno-lto"; fi
  59. check_elf
  60. # determine endianess
  61. echo '#include <stdint.h>' >/tmp/getoffs.c
  62. echo "const int32_t val = 1;" >>/tmp/getoffs.c
  63. compile_rodata
  64. ENDIAN=$(if [ "$rodata" -eq 1 ]; then echo be; else echo le; fi)
  65. # output header
  66. echo "/* autogenerated by mkoffset.sh, do not edit */" >$fn
  67. echo "/* target endianess: $ENDIAN, compiled with: $CC $CFLAGS */" >>$fn
  68. # output offsets
  69. get_define OFS_Pico_ Pico video reg ; echo "$line" >>$fn
  70. get_define OFS_Pico_ Pico m rotate ; echo "$line" >>$fn
  71. get_define OFS_Pico_ Pico m z80Run ; echo "$line" >>$fn
  72. get_define OFS_Pico_ Pico m dirtyPal ; echo "$line" >>$fn
  73. get_define OFS_Pico_ Pico m hardware ; echo "$line" >>$fn
  74. get_define OFS_Pico_ Pico m z80_reset ; echo "$line" >>$fn
  75. get_define OFS_Pico_ Pico m sram_reg ; echo "$line" >>$fn
  76. get_define OFS_Pico_ Pico sv ; echo "$line" >>$fn
  77. get_define OFS_Pico_ Pico sv data ; echo "$line" >>$fn
  78. get_define OFS_Pico_ Pico sv start ; echo "$line" >>$fn
  79. get_define OFS_Pico_ Pico sv end ; echo "$line" >>$fn
  80. get_define OFS_Pico_ Pico sv flags ; echo "$line" >>$fn
  81. get_define OFS_Pico_ Pico rom ; echo "$line" >>$fn
  82. get_define OFS_Pico_ Pico romsize ; echo "$line" >>$fn
  83. get_define OFS_Pico_ Pico est ; echo "$line" >>$fn
  84. get_define OFS_EST_ PicoEState DrawScanline ; echo "$line" >>$fn
  85. get_define OFS_EST_ PicoEState rendstatus ; echo "$line" >>$fn
  86. get_define OFS_EST_ PicoEState DrawLineDest ; echo "$line" >>$fn
  87. get_define OFS_EST_ PicoEState HighCol ; echo "$line" >>$fn
  88. get_define OFS_EST_ PicoEState HighPreSpr ; echo "$line" >>$fn
  89. get_define OFS_EST_ PicoEState Pico ; echo "$line" >>$fn
  90. get_define OFS_EST_ PicoEState PicoMem_vram ; echo "$line" >>$fn
  91. get_define OFS_EST_ PicoEState PicoMem_cram ; echo "$line" >>$fn
  92. get_define OFS_EST_ PicoEState PicoOpt ; echo "$line" >>$fn
  93. get_define OFS_EST_ PicoEState Draw2FB ; echo "$line" >>$fn
  94. get_define OFS_EST_ PicoEState HighPal ; echo "$line" >>$fn
  95. get_define OFS_PMEM_ PicoMem vram ; echo "$line" >>$fn
  96. get_define OFS_PMEM_ PicoMem vsram ; echo "$line" >>$fn
  97. get_define OFS_PMEM32x_ Pico32xMem pal_native ; echo "$line" >>$fn
  98. get_define OFS_SH2_ SH2_ is_slave ; echo "$line" >>$fn
  99. get_define OFS_SH2_ SH2_ p_bios ; echo "$line" >>$fn
  100. get_define OFS_SH2_ SH2_ p_da ; echo "$line" >>$fn
  101. get_define OFS_SH2_ SH2_ p_sdram ; echo "$line" >>$fn
  102. get_define OFS_SH2_ SH2_ p_rom ; echo "$line" >>$fn
  103. get_define OFS_SH2_ SH2_ p_dram ; echo "$line" >>$fn
  104. get_define OFS_SH2_ SH2_ p_drcblk_da ; echo "$line" >>$fn
  105. get_define OFS_SH2_ SH2_ p_drcblk_ram ; echo "$line" >>$fn