From c63af0542733e6c78a23f5814bce4a26ddb6b969 Mon Sep 17 00:00:00 2001 From: mid-kid Date: Sat, 12 Jan 2019 14:04:20 +0100 Subject: [PATCH] Allow linker script to consider section attributes The linker script now allows you to assign a section with the same attributes as in the source. To do this, I've removed a check from AssignSectionAddressAndBankByName that would never be triggered, due to that condition being checked before. Shouldn't this and IsSectionSameTypeBankAndAttrs be condensed into a single function? --- include/link/assign.h | 5 +++-- src/link/assign.c | 19 ++++++------------- src/link/script.c | 20 ++++++++++++++++---- test/asm/test.sh | 1 + test/asm/update-refs.sh | 1 + test/link/section-attributes-mismatch.link | 5 +++++ test/link/section-attributes-mismatch.out | 2 ++ test/link/section-attributes.asm | 2 ++ test/link/section-attributes.link | 5 +++++ test/link/section-attributes.out | 0 test/link/test.sh | 9 +++++++++ test/link/update-refs.sh | 7 +++++++ 12 files changed, 57 insertions(+), 19 deletions(-) create mode 100644 test/link/section-attributes-mismatch.link create mode 100644 test/link/section-attributes-mismatch.out create mode 100644 test/link/section-attributes.asm create mode 100644 test/link/section-attributes.link create mode 100644 test/link/section-attributes.out diff --git a/include/link/assign.h b/include/link/assign.h index c32ee64e..7448ed6d 100644 --- a/include/link/assign.h +++ b/include/link/assign.h @@ -36,8 +36,9 @@ void CreateSymbolTable(void); struct sSection *GetSectionByName(const char *name); int32_t IsSectionNameInUse(const char *name); void SetLinkerscriptName(char *tzLinkerscriptFile); -int32_t IsSectionSameTypeBankAndFloating(const char *name, - enum eSectionType type, int32_t bank); +int32_t IsSectionSameTypeBankAndAttrs(const char *name, + enum eSectionType type, int32_t bank, + int32_t org, int32_t align); uint32_t AssignSectionAddressAndBankByName(const char *name, uint32_t address, int32_t bank); diff --git a/src/link/assign.c b/src/link/assign.c index e2c4b1ee..8c3b0bec 100644 --- a/src/link/assign.c +++ b/src/link/assign.c @@ -321,8 +321,9 @@ struct sSection *GetSectionByName(const char *name) return NULL; } -int32_t IsSectionSameTypeBankAndFloating(const char *name, - enum eSectionType type, int32_t bank) +int32_t IsSectionSameTypeBankAndAttrs(const char *name, + enum eSectionType type, int32_t bank, + int32_t org, int32_t align) { const struct sSection *pSection; @@ -340,8 +341,9 @@ int32_t IsSectionSameTypeBankAndFloating(const char *name, * mismatch or not. */ - /* Section must be floating in source */ - if (pSection->nOrg != -1 || pSection->nAlign != 1) + /* Section must have the same attributes or float */ + if ((pSection->nOrg != -1 && pSection->nOrg != org) || + (pSection->nAlign != 1 && pSection->nAlign != align)) return 0; /* It must have the same type in source and linkerscript */ @@ -374,15 +376,6 @@ uint32_t AssignSectionAddressAndBankByName(const char *name, uint32_t address, /* Section has been found. */ - /* - * A section can be left as floating in the code if the location - * is assigned in the linkerscript. - */ - if (pSection->nOrg != -1 || pSection->nAlign != 1) { - errx(1, "Section \"%s\" from linkerscript isn't floating.\n", - name); - } - /* The bank can be left as unassigned or be the same */ if (pSection->nBank != -1 && pSection->nBank != bank) { errx(1, "Section \"%s\" from linkerscript has different bank number than in the source.\n", diff --git a/src/link/script.c b/src/link/script.c index 913b69ad..bf8a436f 100644 --- a/src/link/script.c +++ b/src/link/script.c @@ -23,6 +23,10 @@ static struct { static int32_t current_bank = -1; /* Bank as seen by the bank array */ static int32_t current_real_bank = -1; /* bank as seen by the GB */ +/* Current section attributes */ +static int32_t fix_org = -1; +static int32_t fix_align = 1; + void script_InitSections(void) { int32_t i; @@ -176,6 +180,8 @@ void script_SetAddress(uint32_t addr) bank[current_bank].address, bank[current_bank].top_address); } + + fix_org = addr; } void script_SetAlignment(uint32_t alignment) @@ -200,6 +206,8 @@ void script_SetAlignment(uint32_t alignment) bank[current_bank].address, bank[current_bank].top_address); } + + fix_align = size; } void script_OutputSection(const char *section_name) @@ -209,9 +217,11 @@ void script_OutputSection(const char *section_name) section_name); } - if (!IsSectionSameTypeBankAndFloating(section_name, - bank[current_bank].type, - current_real_bank)) { + if (!IsSectionSameTypeBankAndAttrs(section_name, + bank[current_bank].type, + current_real_bank, + fix_org, + fix_align)) { errx(1, "Different attributes for \"%s\" in source and linkerscript\n", section_name); } @@ -221,5 +231,7 @@ void script_OutputSection(const char *section_name) AssignSectionAddressAndBankByName(section_name, bank[current_bank].address, current_real_bank); -} + fix_org = -1; + fix_align = 1; +} diff --git a/test/asm/test.sh b/test/asm/test.sh index 0cbc38ea..cfd127df 100755 --- a/test/asm/test.sh +++ b/test/asm/test.sh @@ -20,4 +20,5 @@ for i in *.asm; do fi done +rm -f $o $gb $before $after exit $rc diff --git a/test/asm/update-refs.sh b/test/asm/update-refs.sh index d956ff31..b8b22a19 100755 --- a/test/asm/update-refs.sh +++ b/test/asm/update-refs.sh @@ -6,4 +6,5 @@ for i in *.asm; do mv -f $fname ${i%.asm}.out done +rm -f $fname exit 0 diff --git a/test/link/section-attributes-mismatch.link b/test/link/section-attributes-mismatch.link new file mode 100644 index 00000000..e9cf75af --- /dev/null +++ b/test/link/section-attributes-mismatch.link @@ -0,0 +1,5 @@ +ROM0 + org $10 + "sec" + org $20 + "secfix" diff --git a/test/link/section-attributes-mismatch.out b/test/link/section-attributes-mismatch.out new file mode 100644 index 00000000..e7ac2a38 --- /dev/null +++ b/test/link/section-attributes-mismatch.out @@ -0,0 +1,2 @@ +error: Different attributes for "sec" in source and linkerscript + diff --git a/test/link/section-attributes.asm b/test/link/section-attributes.asm new file mode 100644 index 00000000..db5b596c --- /dev/null +++ b/test/link/section-attributes.asm @@ -0,0 +1,2 @@ +SECTION "sec",ROM0,ALIGN[4] +SECTION "secfix",ROM0[$20] diff --git a/test/link/section-attributes.link b/test/link/section-attributes.link new file mode 100644 index 00000000..7d62322a --- /dev/null +++ b/test/link/section-attributes.link @@ -0,0 +1,5 @@ +ROM0 + align 4 + "sec" + org $20 + "secfix" diff --git a/test/link/section-attributes.out b/test/link/section-attributes.out new file mode 100644 index 00000000..e69de29b diff --git a/test/link/test.sh b/test/link/test.sh index fdb95555..df4812f2 100755 --- a/test/link/test.sh +++ b/test/link/test.sh @@ -16,6 +16,14 @@ head -c 20 $gbtemp > $otemp 2>&1 diff bank-numbers.out.bin $otemp rc=$(($? || $rc)) +$RGBASM -o $otemp section-attributes.asm +$RGBLINK -l section-attributes.link -o $gbtemp $otemp > $outtemp 2>&1 +diff section-attributes.out $outtemp +rc=$(($? || $rc)) +$RGBLINK -l section-attributes-mismatch.link -o $gbtemp $otemp > $outtemp 2>&1 +diff section-attributes-mismatch.out $outtemp +rc=$(($? || $rc)) + $RGBASM -o $otemp wramx-dmg-mode.asm $RGBLINK -o $gbtemp $otemp > $outtemp 2>&1 diff wramx-dmg-mode-no-d.out $outtemp @@ -60,4 +68,5 @@ $RGBLINK -o $gbtemp $otemp diff all-instructions.out.bin $gbtemp rc=$(($? || $rc)) +rm -f $otemp $gbtemp $gbtemp2 $outtemp exit $rc diff --git a/test/link/update-refs.sh b/test/link/update-refs.sh index 0968c59a..6636d109 100755 --- a/test/link/update-refs.sh +++ b/test/link/update-refs.sh @@ -9,6 +9,12 @@ $RGBASM -o $otemp bank-numbers.asm $RGBLINK -o $gbtemp $otemp > bank-numbers.out 2>&1 head -c 20 $gbtemp > bank-numbers.out.bin 2>&1 +$RGBASM -o $otemp section-attributes.asm +$RGBLINK -l section-attributes.link \ + -o $gbtemp $otemp > section-attributes.out 2>&1 +$RGBLINK -l section-attributes-mismatch.link \ + -o $gbtemp $otemp > section-attributes-mismatch.out 2>&1 + $RGBASM -o $otemp wramx-dmg-mode.asm $RGBLINK -o $gbtemp $otemp > wramx-dmg-mode-no-d.out 2>&1 $RGBLINK -d -o $gbtemp $otemp > wramx-dmg-mode-d.out 2>&1 @@ -28,4 +34,5 @@ $RGBLINK -t -o $gbtemp $otemp > romx-tiny-t.out 2>&1 $RGBASM -o $otemp all-instructions.asm $RGBLINK -o all-instructions.out.bin $otemp 2>&1 +rm -f $otemp $gbtemp exit 0