Skip to content

Instantly share code, notes, and snippets.

@SonoSooS
Created February 22, 2017 21:42
Show Gist options
  • Save SonoSooS/f70c7d34f458a4b26c6691db64d48dbc to your computer and use it in GitHub Desktop.
Save SonoSooS/f70c7d34f458a4b26c6691db64d48dbc to your computer and use it in GitHub Desktop.
.cia -> .elf
#!/bin/bash
set -e
FN="$(basename "$1" .cia)_tmp"
rm -rf "$FN"
mkdir "$FN"
ctrtool --contents="$FN/contents" "$1" >/dev/null
ctrtool --exefsdir="$FN/exefs" --decompresscode "$FN/contents.0000.00000000" >/dev/null
ASD="$(ctrtool "$FN/contents.0000.00000000" | grep Code)"
TEXT_ADDR=$(echo $ASD | sed 's/.*Code text address: \(0x[0-9A-F]*\).*/\1/')
CORO_ADDR=$(echo $ASD | sed 's/.*Code ro address: \(0x[0-9A-F]*\).*/\1/')
CORW_ADDR=$(echo $ASD | sed 's/.*Code data address: \(0x[0-9A-F]*\).*/\1/')
TEXT_FSIZ=$(echo $ASD | sed 's/.*Code text size: \(0x[0-9A-F]*\).*/\1/')
CORO_FSIZ=$(echo $ASD | sed 's/.*Code ro size: \(0x[0-9A-F]*\).*/\1/')
CORW_FSIZ=$(echo $ASD | sed 's/.*Code data size: \(0x[0-9A-F]*\).*/\1/')
TEXT_SKIP=$(echo $ASD | sed 's/.*Code text max pages: 0x[0-9A-F]* (\(0x[0-9A-F]*\)).*/\1/')
CORO_SKIP=$(echo $ASD | sed 's/.*Code ro max pages: 0x[0-9A-F]* (\(0x[0-9A-F]*\)).*/\1/')
CORW_SKIP=$(echo $ASD | sed 's/.*Code data max pages: 0x[0-9A-F]* (\(0x[0-9A-F]*\)).*/\1/')
CBSS_SIZE=$(echo $ASD | sed 's/.*Code bss size: \(0x[0-9A-F]*\).*/\1/')
CSTK_SIZE=$(echo $ASD | sed 's/.*Code stack size: \(0x[0-9A-F]*\).*/\1/')
dd if="$FN/exefs/code.bin" bs=1 count=$((TEXT_FSIZ)) 2>/dev/null | pv >"$FN/text.bin"
dd if="$FN/exefs/code.bin" bs=1 count=$((CORO_FSIZ)) skip=$((TEXT_SKIP)) 2>/dev/null | pv >"$FN/ro.bin"
dd if="$FN/exefs/code.bin" bs=1 count=$((CORW_FSIZ)) skip=$((TEXT_SKIP + CORO_SKIP)) 2>/dev/null | pv >"$FN/rw.bin"
arm-none-eabi-objcopy -I binary -O elf32-littlearm --rename-section .data=.text "$FN/text.bin" "$FN/text.o"
arm-none-eabi-objcopy -I binary -O elf32-littlearm --rename-section .data=.rodata "$FN/ro.bin" "$FN/ro.o"
arm-none-eabi-objcopy -I binary -O elf32-littlearm --rename-section .data=.data "$FN/rw.bin" "$FN/rw.o"
cat >"$FN/e2elf.ld" <<EOF
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
MEMORY
{
EOF
echo " textregion : ORIGIN = $TEXT_ADDR, LENGTH = $TEXT_SKIP" >>"$FN/e2elf.ld"
echo " roregion : ORIGIN = $CORO_ADDR, LENGTH = $CORO_SKIP" >>"$FN/e2elf.ld"
echo " rwregion : ORIGIN = $CORW_ADDR, LENGTH = $((CORW_SKIP + CBSS_SIZE))" >>"$FN/e2elf.ld"
cat >>"$FN/e2elf.ld" <<EOF
}
PHDRS
{
text PT_LOAD FLAGS(5);
rodata PT_LOAD FLAGS(4);
data PT_LOAD FLAGS(6);
bss PT_LOAD;
}
SECTIONS
{
.init : ALIGN(4)
{
__text_start = .;
KEEP (*(.init))
} >textregion :text
.text : ALIGN (4)
{
*(.text*)
*(.stub)
*(.gnu.warning)
*(.gnu.linkonce.t*)
*(.glue_7)
*(.glue_7t)
} >textregion
__text_end = .;
.rodata :
{
*(.rodata)
*all.rodata*(*)
*(.roda)
*(.rodata.*)
*(.gnu.linkonce.r*)
SORT(CONSTRUCTORS)
} >roregion :rodata
.data :
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
} >rwregion :data
.bss :
{
EOF
echo " . = . + $CBSS_SIZE;" >>"$FN/e2elf.ld"
cat >>"$FN/e2elf.ld" <<EOF
} >rwregion :bss
__bss_end = .;
__bss_end__ = .;
_end = .;
__end__ = .;
PROVIDE (end = _end);
EOF
echo " .stack $CSTK_SIZE : { _stack = .; *(.stack) }" >>"$FN/e2elf.ld"
echo "}" >>"$FN/e2elf.ld"
arm-none-eabi-ld --accept-unknown-input-arch -T "$FN/e2elf.ld" -o "$(basename $1 .cia).elf" "$FN/text.o" "$FN/ro.o" "$FN/rw.o"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment