From: Aaron Taylor Date: Thu, 12 Nov 2020 02:07:51 +0000 (-0800) Subject: Carved out a space on website for a page about modern C development for PDP-11. X-Git-Url: http://git.subgeniuskitty.com/website_subgeniuskitty.com/.git/commitdiff_plain/4f5e6ebe7a4e8bdd5229ab9f4f1463da0afdcc8b Carved out a space on website for a page about modern C development for PDP-11. --- diff --git a/data/development/pdp-11/modern_c_software_development/gcc_bugs.md b/data/development/pdp-11/modern_c_software_development/gcc_bugs.md new file mode 100644 index 0000000..e0c6b67 --- /dev/null +++ b/data/development/pdp-11/modern_c_software_development/gcc_bugs.md @@ -0,0 +1,88 @@ +# Overview # + +Although GCC claims to support PDP-11 targets there are some bugs that must be +worked around both in GCC and the GNU assembler. + +# GNU binutils Bugs # + +## Problem Description ## + +One of the addressing modes supported by the PDP-11 is 'index deferred', +represented by `@X(Rn)`. This operand indicates that `Rn` contains a pointer +which should be dereferenced and the result added to `X` to generate a new +pointer to the final location. For example, consider the following four values, +one stored in a register and the other three in memory. Then `@2(R1)` is the +value `222`. + + R1: 1000 + 1000: 2000 + 2000: 111 + 2002: 222 + +Similarly, `@0(R1)` is the value `111`. In most PDP-11 assemblers, including +DEC's MACRO-11 assembler, the string `@(Rn)` is an alias to `@0(Rn)`. But when +the GNU assembler encounters `@(Rn)` it assembles it as though it were `(Rn)`, +a single level of indirection instead of two levels! + +If we're only writing assembly then we can work around this bug by always using +the form `@0(Rn)`. But what if we're writing C and using GCC to compile it? +Consider the following C code example, taken directly from some stack-based +debugger code written for the PDP-11. + + uint16_t ** csp = (uint16_t **) 070000; + *csp = (uint16_t *) 060000; + **csp = 0; + +When GCC transpiles this to assembly it generates code of the form `@(Rn)` when +assigning a value to `**csp` thus causing the value `0` to overwrite the value +`060000` at `*csp` if GNU `as` is used to assemble the code. + +## Solution Description ## + +The following patch, tested on GNU binutils 2.28, fixes the bug. Since it +overloads the `operand->code` variable to pass unrelated state information to +`parse_reg()` I haven't submitted it for inclusion in GNU binutils. Once I'm +done bug-hunting in my toolchain I will clean up all the fixes and submit them +in one bundle. + + --- tc-pdp11.c 2017-06-24 22:33:00.260210000 -0700 + +++ tc-pdp11.c.fixed 2017-06-24 22:32:12.455205000 -0700 + @@ -431,6 +431,9 @@ + { + LITTLENUM_TYPE literal_float[2]; + + + /* Store the value (if any) passed by parse_op_noreg() before parse_reg() overwrites it. */ + + int deferred = operand->code; + + + str = skip_whitespace (str); + + switch (*str) + @@ -451,6 +454,15 @@ + operand->code |= 020; + str++; + } + + /* + + * This catches the case where @(Rn) is interpreted as (Rn) rather than @0(Rn) + + */ + + else if (deferred) + + { + + operand->additional = 1; + + operand->word = 0; + + operand->code |= 060; + + } + else + { + operand->code |= 010; + @@ -581,6 +593,12 @@ + + if (*str == '@' || *str == '*') + { + + /* + + * operand->code is overwritten by parse_reg() inside parse_op_no_deferred() + + * We use it to temporarily catch the alias @(Rn) -> @0(Rn) since + + * parse_op_no_deferred() starts at str+1 and thus misses the '@'. + + */ + + operand->code |= 010; + str = parse_op_no_deferred (str + 1, operand); + if (operand->error) + return str; diff --git a/data/development/pdp-11/modern_c_software_development/gcc_bugs.metadata b/data/development/pdp-11/modern_c_software_development/gcc_bugs.metadata new file mode 100644 index 0000000..0df03fb --- /dev/null +++ b/data/development/pdp-11/modern_c_software_development/gcc_bugs.metadata @@ -0,0 +1,6 @@ +[DEFAULT] +page_title = GCC PDP-11 Cross-Compiling Bugs +meta_keywords = +meta_description = +menu_text = GCC Bugs +menu_priority = diff --git a/data/development/pdp-11/modern_c_software_development/index.md b/data/development/pdp-11/modern_c_software_development/index.md new file mode 100644 index 0000000..ee65cd4 --- /dev/null +++ b/data/development/pdp-11/modern_c_software_development/index.md @@ -0,0 +1,4 @@ +# Overview # + +Developing baremetal software for the PDP-11 in a modern C environment. + diff --git a/data/development/pdp-11/modern_c_software_development/index.metadata b/data/development/pdp-11/modern_c_software_development/index.metadata new file mode 100644 index 0000000..5dc0b59 --- /dev/null +++ b/data/development/pdp-11/modern_c_software_development/index.metadata @@ -0,0 +1,6 @@ +[DEFAULT] +page_title = Modern C for baremetal PDP-11 software development +meta_keywords = +meta_description = +menu_text = Modern Software Devel +menu_priority = 8000 diff --git a/data/development/pdp-11/software_development/2.11BSD/index.md b/data/development/pdp-11/software_development/2.11BSD/index.md deleted file mode 100644 index 8629a75..0000000 --- a/data/development/pdp-11/software_development/2.11BSD/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Overview # - -Software development under 2.11BSD. diff --git a/data/development/pdp-11/software_development/2.11BSD/index.metadata b/data/development/pdp-11/software_development/2.11BSD/index.metadata deleted file mode 100644 index 8e1c830..0000000 --- a/data/development/pdp-11/software_development/2.11BSD/index.metadata +++ /dev/null @@ -1,6 +0,0 @@ -[DEFAULT] -page_title = PDP-11 Software Development in 2.11BSD -meta_keywords = -meta_description = -menu_text = 2.11BSD -menu_priority = 9000 diff --git a/data/development/pdp-11/software_development/index.md b/data/development/pdp-11/software_development/index.md deleted file mode 100644 index 9aed112..0000000 --- a/data/development/pdp-11/software_development/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Overview # - -PDP-11 software development. diff --git a/data/development/pdp-11/software_development/index.metadata b/data/development/pdp-11/software_development/index.metadata deleted file mode 100644 index c134dfd..0000000 --- a/data/development/pdp-11/software_development/index.metadata +++ /dev/null @@ -1,6 +0,0 @@ -[DEFAULT] -page_title = PDP-11 Software Development -meta_keywords = -meta_description = -menu_text = Software Devel -menu_priority = 9000 diff --git a/data/development/pdp-11/software_development/modern_unix/gcc_bugs.md b/data/development/pdp-11/software_development/modern_unix/gcc_bugs.md deleted file mode 100644 index e0c6b67..0000000 --- a/data/development/pdp-11/software_development/modern_unix/gcc_bugs.md +++ /dev/null @@ -1,88 +0,0 @@ -# Overview # - -Although GCC claims to support PDP-11 targets there are some bugs that must be -worked around both in GCC and the GNU assembler. - -# GNU binutils Bugs # - -## Problem Description ## - -One of the addressing modes supported by the PDP-11 is 'index deferred', -represented by `@X(Rn)`. This operand indicates that `Rn` contains a pointer -which should be dereferenced and the result added to `X` to generate a new -pointer to the final location. For example, consider the following four values, -one stored in a register and the other three in memory. Then `@2(R1)` is the -value `222`. - - R1: 1000 - 1000: 2000 - 2000: 111 - 2002: 222 - -Similarly, `@0(R1)` is the value `111`. In most PDP-11 assemblers, including -DEC's MACRO-11 assembler, the string `@(Rn)` is an alias to `@0(Rn)`. But when -the GNU assembler encounters `@(Rn)` it assembles it as though it were `(Rn)`, -a single level of indirection instead of two levels! - -If we're only writing assembly then we can work around this bug by always using -the form `@0(Rn)`. But what if we're writing C and using GCC to compile it? -Consider the following C code example, taken directly from some stack-based -debugger code written for the PDP-11. - - uint16_t ** csp = (uint16_t **) 070000; - *csp = (uint16_t *) 060000; - **csp = 0; - -When GCC transpiles this to assembly it generates code of the form `@(Rn)` when -assigning a value to `**csp` thus causing the value `0` to overwrite the value -`060000` at `*csp` if GNU `as` is used to assemble the code. - -## Solution Description ## - -The following patch, tested on GNU binutils 2.28, fixes the bug. Since it -overloads the `operand->code` variable to pass unrelated state information to -`parse_reg()` I haven't submitted it for inclusion in GNU binutils. Once I'm -done bug-hunting in my toolchain I will clean up all the fixes and submit them -in one bundle. - - --- tc-pdp11.c 2017-06-24 22:33:00.260210000 -0700 - +++ tc-pdp11.c.fixed 2017-06-24 22:32:12.455205000 -0700 - @@ -431,6 +431,9 @@ - { - LITTLENUM_TYPE literal_float[2]; - - + /* Store the value (if any) passed by parse_op_noreg() before parse_reg() overwrites it. */ - + int deferred = operand->code; - + - str = skip_whitespace (str); - - switch (*str) - @@ -451,6 +454,15 @@ - operand->code |= 020; - str++; - } - + /* - + * This catches the case where @(Rn) is interpreted as (Rn) rather than @0(Rn) - + */ - + else if (deferred) - + { - + operand->additional = 1; - + operand->word = 0; - + operand->code |= 060; - + } - else - { - operand->code |= 010; - @@ -581,6 +593,12 @@ - - if (*str == '@' || *str == '*') - { - + /* - + * operand->code is overwritten by parse_reg() inside parse_op_no_deferred() - + * We use it to temporarily catch the alias @(Rn) -> @0(Rn) since - + * parse_op_no_deferred() starts at str+1 and thus misses the '@'. - + */ - + operand->code |= 010; - str = parse_op_no_deferred (str + 1, operand); - if (operand->error) - return str; diff --git a/data/development/pdp-11/software_development/modern_unix/gcc_bugs.metadata b/data/development/pdp-11/software_development/modern_unix/gcc_bugs.metadata deleted file mode 100644 index 0df03fb..0000000 --- a/data/development/pdp-11/software_development/modern_unix/gcc_bugs.metadata +++ /dev/null @@ -1,6 +0,0 @@ -[DEFAULT] -page_title = GCC PDP-11 Cross-Compiling Bugs -meta_keywords = -meta_description = -menu_text = GCC Bugs -menu_priority = diff --git a/data/development/pdp-11/software_development/modern_unix/index.md b/data/development/pdp-11/software_development/modern_unix/index.md deleted file mode 100644 index afe7841..0000000 --- a/data/development/pdp-11/software_development/modern_unix/index.md +++ /dev/null @@ -1,3 +0,0 @@ -# Overview # - -Software development in modern UNIX. diff --git a/data/development/pdp-11/software_development/modern_unix/index.metadata b/data/development/pdp-11/software_development/modern_unix/index.metadata deleted file mode 100644 index 092a69c..0000000 --- a/data/development/pdp-11/software_development/modern_unix/index.metadata +++ /dev/null @@ -1,6 +0,0 @@ -[DEFAULT] -page_title = PDP-11 Software Development in Modern UNIX -meta_keywords = -meta_description = -menu_text = Modern UNIX -menu_priority = 9000