mirror of
				https://github.com/RaySollium99/picodrive.git
				synced 2025-10-27 00:29:39 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			167 lines
		
	
	
	
		
			6.5 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			167 lines
		
	
	
	
		
			6.5 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable file
		
	
	
	
	
| # automatically compute structure offsets for gcc targets in ELF format
 | |
| # (C) 2018 Kai-Uwe Bloem. This work is placed in the public domain.
 | |
| #
 | |
| # usage: mkoffsets <output dir>
 | |
| 
 | |
| CC=${CC:-gcc}
 | |
| 
 | |
| # endianess of target (automagically determined below)
 | |
| ENDIAN=
 | |
| 
 | |
| # check which object format to dissect
 | |
| READELF=
 | |
| OBJDUMP=
 | |
| check_obj ()
 | |
| {
 | |
| 	# prepare an object file; as side effect dtermine the endianess
 | |
| 	CROSS=$(echo $CC | sed 's/gcc.*//')
 | |
| 	echo '#include <stdint.h>' >/tmp/getoffs.c
 | |
| 	echo "const int32_t val = 1;" >>/tmp/getoffs.c
 | |
| 	$CC $CFLAGS -I .. -c /tmp/getoffs.c -o /tmp/getoffs.o || exit 1
 | |
| 
 | |
| 	# check for readelf; readelf is the only toolchain tool not using bfd,
 | |
| 	# hence it works with ELF files for every target
 | |
| 	if file /tmp/getoffs.o | grep -q ELF; then
 | |
| 		if command -v readelf >/dev/null; then
 | |
| 			READELF=readelf
 | |
| 		elif command -v ${CROSS}readelf >/dev/null; then
 | |
| 			READELF=${CROSS}readelf
 | |
| 		fi
 | |
| 	fi
 | |
| 	if [ -n "$READELF" ]; then
 | |
| 		# find the the .rodata section (in case -fdata-sections is used)
 | |
| 		rosect=$($READELF -S /tmp/getoffs.o | grep '\.rodata\|\.sdata' |
 | |
| 						sed 's/^[^.]*././;s/ .*//')
 | |
| 		# read .rodata section as hex string (should be only 4 bytes)
 | |
| 		ro=$($READELF -x $rosect /tmp/getoffs.o | grep '0x' | cut -c14-48 |
 | |
| 						tr -d ' \n' | cut -c1-8)
 | |
| 		# if no output could be read readelf isn't working
 | |
| 		if [ -z "$ro" ]; then
 | |
| 			READELF=
 | |
| 		fi
 | |
| 	fi
 | |
| 	# if there is no working readelf try using objdump
 | |
| 	if [ -z "$READELF" ]; then
 | |
| 		# objdump is using bfd; try using the toolchain objdump first
 | |
| 		# since this is likely working with the toolchain objects
 | |
| 		if command -v ${CROSS}objdump >/dev/null; then
 | |
| 			OBJDUMP=${CROSS}objdump
 | |
| 		elif command -v objdump >/dev/null; then
 | |
| 			OBJDUMP=objdump
 | |
| 		fi
 | |
| 		# find the start line of the .rodata section; read the next line
 | |
| 		ro=$($OBJDUMP -s /tmp/getoffs.o | awk '\
 | |
| 		  /Contents of section.*(__const|.r[o]?data|.sdata)/ {o=1; next} \
 | |
| 		  {if(o) { gsub(/  .*/,""); $1=""; gsub(/ /,""); print; exit}}')
 | |
| 		# no working tool for extracting the ro data; stop here
 | |
| 		if [ -z "$ro" ]; then
 | |
| 			echo "/* mkoffset.sh: no readelf or not ELF, offset table not created */" >$fn
 | |
| 			echo "WARNING: no readelf or not ELF, offset table not created"
 | |
| 			exit
 | |
| 		fi
 | |
| 	fi
 | |
| 	# extract decimal value from ro
 | |
| 	rodata=$(printf "%d" 0x$ro)
 | |
| 	ENDIAN=$(if [ "$rodata" -eq 1 ]; then echo be; else echo le; fi)
 | |
| }
 | |
| 
 | |
| # compile with target C compiler and extract value from .rodata section
 | |
| compile_rodata ()
 | |
| {
 | |
| 	$CC $CFLAGS -I .. -c /tmp/getoffs.c -o /tmp/getoffs.o || exit 1
 | |
| 	if [ -n "$READELF" ]; then
 | |
| 		# find the .rodata section (in case -fdata-sections is used)
 | |
| 		rosect=$(readelf -S /tmp/getoffs.o | grep '\.rodata\|\.sdata' |
 | |
| 						sed 's/^[^.]*././;s/ .*//')
 | |
| 		# read .rodata section as hex string (should be only 4 bytes)
 | |
| 		ro=$(readelf -x $rosect /tmp/getoffs.o | grep '0x' | cut -c14-48 |
 | |
| 						tr -d ' \n' | cut -c1-8)
 | |
| 	elif [ -n "$OBJDUMP" ]; then
 | |
| 		# find the start line of the .rodata section; read the next line
 | |
| 		ro=$($OBJDUMP -s /tmp/getoffs.o | awk '\
 | |
| 		  /Contents of section.*(__const|.r[o]?data|.sdata)/ {o=1; next} \
 | |
| 		  {if(o) { gsub(/  .*/,""); $1=""; gsub(/ /,""); print; exit}}')
 | |
| 	fi
 | |
| 	if [ "$ENDIAN" = "le" ]; then
 | |
| 		# swap needed for le target
 | |
| 		hex=""
 | |
| 		for b in $(echo $ro | sed 's/\([0-9a-f]\{2\}\)/\1 /g'); do
 | |
| 			hex=$b$hex;
 | |
| 		done
 | |
| 	else
 | |
| 		hex=$ro
 | |
| 	fi
 | |
| 	# extract decimal value from hex string
 | |
| 	rodata=$(printf "%d" 0x$hex)
 | |
| }
 | |
| 
 | |
| # determine member offset and create #define
 | |
| get_define () # prefix struct member member...
 | |
| {
 | |
| 	prefix=$1; shift
 | |
| 	struct=$1; shift
 | |
| 	field=$(echo $* | sed 's/ /./g')
 | |
| 	name=$(echo $* | sed 's/ /_/g')
 | |
| 	echo '#include <stdint.h>' > /tmp/getoffs.c
 | |
| 	echo '#include <pico/pico_int.h>' >> /tmp/getoffs.c
 | |
| 	echo "static struct $struct p;" >> /tmp/getoffs.c
 | |
| 	echo "const int32_t val = (char *)&p.$field - (char*)&p;" >>/tmp/getoffs.c
 | |
| 	compile_rodata
 | |
| 	line=$(printf "#define %-20s 0x%04x" $prefix$name $rodata)
 | |
| }
 | |
| 
 | |
| fn="${1:-.}/pico_int_offs.h"
 | |
| if echo $CFLAGS | grep -qe -flto; then CFLAGS="$CFLAGS -fno-lto"; fi
 | |
| 
 | |
| check_obj
 | |
| # output header
 | |
| echo "/* autogenerated by mkoffset.sh, do not edit */" >$fn
 | |
| echo "/* target endianess: $ENDIAN, compiled with: $CC $CFLAGS */" >>$fn
 | |
| # output offsets
 | |
| get_define OFS_Pico_ Pico video reg		; echo "$line" >>$fn
 | |
| get_define OFS_Pico_ Pico m rotate		; echo "$line" >>$fn
 | |
| get_define OFS_Pico_ Pico m z80Run		; echo "$line" >>$fn
 | |
| get_define OFS_Pico_ Pico m dirtyPal		; echo "$line" >>$fn
 | |
| get_define OFS_Pico_ Pico m hardware		; echo "$line" >>$fn
 | |
| get_define OFS_Pico_ Pico m z80_reset		; echo "$line" >>$fn
 | |
| get_define OFS_Pico_ Pico m sram_reg		; echo "$line" >>$fn
 | |
| get_define OFS_Pico_ Pico sv			; echo "$line" >>$fn
 | |
| get_define OFS_Pico_ Pico sv data		; echo "$line" >>$fn
 | |
| get_define OFS_Pico_ Pico sv start		; echo "$line" >>$fn
 | |
| get_define OFS_Pico_ Pico sv end		; echo "$line" >>$fn
 | |
| get_define OFS_Pico_ Pico sv flags		; echo "$line" >>$fn
 | |
| get_define OFS_Pico_ Pico rom			; echo "$line" >>$fn
 | |
| get_define OFS_Pico_ Pico romsize		; echo "$line" >>$fn
 | |
| get_define OFS_Pico_ Pico est			; echo "$line" >>$fn
 | |
| 
 | |
| get_define OFS_PicoIn_ PicoInterface opt	; echo "$line" >>$fn
 | |
| get_define OFS_PicoIn_ PicoInterface filter	; echo "$line" >>$fn
 | |
| get_define OFS_PicoIn_ PicoInterface AHW	; echo "$line" >>$fn
 | |
| 
 | |
| get_define OFS_EST_ PicoEState DrawScanline	; echo "$line" >>$fn
 | |
| get_define OFS_EST_ PicoEState rendstatus	; echo "$line" >>$fn
 | |
| get_define OFS_EST_ PicoEState DrawLineDest	; echo "$line" >>$fn
 | |
| get_define OFS_EST_ PicoEState DrawLineDestIncr	; echo "$line" >>$fn
 | |
| get_define OFS_EST_ PicoEState HighCol		; echo "$line" >>$fn
 | |
| get_define OFS_EST_ PicoEState HighPreSpr	; echo "$line" >>$fn
 | |
| get_define OFS_EST_ PicoEState Pico		; echo "$line" >>$fn
 | |
| get_define OFS_EST_ PicoEState PicoMem_vram	; echo "$line" >>$fn
 | |
| get_define OFS_EST_ PicoEState PicoMem_cram	; echo "$line" >>$fn
 | |
| get_define OFS_EST_ PicoEState PicoOpt		; echo "$line" >>$fn
 | |
| get_define OFS_EST_ PicoEState Draw2FB		; echo "$line" >>$fn
 | |
| get_define OFS_EST_ PicoEState Draw2Width	; echo "$line" >>$fn
 | |
| get_define OFS_EST_ PicoEState Draw2Start	; echo "$line" >>$fn
 | |
| get_define OFS_EST_ PicoEState HighPal		; echo "$line" >>$fn
 | |
| 
 | |
| get_define OFS_PMEM_ PicoMem vram		; echo "$line" >>$fn
 | |
| get_define OFS_PMEM_ PicoMem vsram		; echo "$line" >>$fn
 | |
| get_define OFS_PMEM32x_ Pico32xMem pal_native	; echo "$line" >>$fn
 | |
| 
 | |
| get_define OFS_SH2_ SH2_ is_slave		; echo "$line" >>$fn
 | |
| get_define OFS_SH2_ SH2_ p_bios			; echo "$line" >>$fn
 | |
| get_define OFS_SH2_ SH2_ p_da			; echo "$line" >>$fn
 | |
| get_define OFS_SH2_ SH2_ p_sdram		; echo "$line" >>$fn
 | |
| get_define OFS_SH2_ SH2_ p_rom			; echo "$line" >>$fn
 | |
| get_define OFS_SH2_ SH2_ p_dram			; echo "$line" >>$fn
 | |
| get_define OFS_SH2_ SH2_ p_drcblk_da		; echo "$line" >>$fn
 | |
| get_define OFS_SH2_ SH2_ p_drcblk_ram		; echo "$line" >>$fn
 | 
