Close
0%
0%

A stack.

It started as a software data stack. Because I need it. It has become a hardware control stack.

Similar projects worth following
C's standard ABI is ridiculous.

Work in progress.

This project describes a part of an ABI that looks like old-school Pascal, except that a hardware stack (or something emulating it) is much safer and faster. It does not need to change most high-level source code but compilers, libraries, linkers, processors etc. must account for:

  • a software-defined data stack (to store the function's frame containing local variables)
  • a hardware control-only stack (for call/return, looping or try/throw/catch for example).

The software data stack is a very old trick so nothing to say about it. The hardware stack however pulls a few tricks from its sleeves.

.

Implementations considered for #YGREC32 and #F-CPU.

Stay tuned.

.

 
-o-O-0-O-o-
 

Logs:
1. First article
2. First code
3. First archive
4. Use-after-free
5. anti-break do()
.
.
.
.
.

stack_20250413.tgz

added the mark macro

x-compressed-tar - 3.95 kB - 04/13/2025 at 17:33

Download

stack_alloc.20250412.tgz

double-while-loop prevents break bypass.

x-compressed-tar - 3.60 kB - 04/12/2025 at 00:16

Download

stack_alloc.tgz

Supports clear_ptr()

x-compressed-tar - 3.53 kB - 03/05/2025 at 00:15

Download

data_stack.tgz

supports DATA_STACK_ADJUSTABLE DATA_STACK_DESTRUCTOR DATA_STACK_MAXALLOC

x-compressed-tar - 2.94 kB - 03/03/2025 at 12:35

Download

  • anti-break do()

    Yann Guidon / YGDES04/12/2025 at 00:27 0 comments

    I added an inner loop inside the DS_MARK-DS_RELEASE macro :

    // The inseparable pair :
    #define DS_MARK                      \
    do {                                 \
      datastack_mark_type mark_variable; \
      DO_MARK(mark_variable);            \
      do {
    
    // double-loop prevents break from skipping the release
    
    #define DS_RELEASE                            \
      } while(0);                                 \
      scan_destructors(mark_variable.destructor); \
      DO_RELEASE(mark_variable);                  \
    } while(0);

    It only occurred to me that a break between the two macros would skip the release... now it's fixed.

  • Use-after-free

    Yann Guidon / YGDES03/05/2025 at 00:32 0 comments

    I just dropped stack_alloc.tgz

    This addresses a big concern, the hard way : you can clear a pointer after the corresponding block has been freed by RELEASE. So if you use this pointer after, you SEGFAULT.

    Of course, this pointer should not have been copied elsewhere because there is no reference count but at least you have an "early safety blanket" in case of bug : fail early and find out why before it's too intricate.

    From example_clearptr.c:

      // How it should ideally be done:
      DS_MARK
        puts("1st version: should work smoothly.");
        char *ch1=new(32);
        memcpy(ch1, alphabet, 27);
        puts(ch1);
      DS_RELEASE
      // ch1 is out of declaration scope here and
      // can't be used after DS_RELEASE freed it.
    
      // Less ideal version where the pointer gets
      // NULLed by the destructor to prevent use-after-free
      char *ch2;
      DS_MARK
        puts("2nd version: must SEGFAULT:");
        new_clear(32, ch2);
        memcpy(ch2, alphabet+3, 27-3);
        // puts must work here
      DS_RELEASE
      // puts shouldn't work here because the pointer has been freed.
      puts(ch2);
    

    It's quite brutal but it works without being overkill !

  • First archive

    Yann Guidon / YGDES03/03/2025 at 17:40 0 comments

    The core code uses about 330 lines (.c+.h) and can now be found, without the aStrA part, there :

    data_stack.tgz

    It supports three options:

    • DATA_STACK_ADJUSTABLE : allows the top object to be grown or shrunk after new().
    • DATA_STACK_DESTRUCTOR : an "object" can be associated with a function pointer, called in reverse order "like a local atexit()"
    • DATA_STACK_MAXALLOC : collect maximum stack depth/usage.

    Two example programs are provided.

  • First code

    Yann Guidon / YGDES12/28/2024 at 08:56 0 comments

    So I was working on the #aStrA : Aligned Strings format with attributesand the principles have resurfaced.

    I also write an article on the subject, the current dev snapshot is at AS20241228.tgz.

    It's still a dumb mark-new-release allocator but it is multithread-compatible, you can locate the buffer anywhere you like in data memory.

  • First article

    Yann Guidon / YGDES05/08/2024 at 00:52 0 comments

    A first article is now available in the French new stands in May-June 2024:

    It's only the first part of a trilogy that explains many of the practical shortcomings of the C-style ABI that makes our lives so miserable. Beware of the C hacks...

View all 5 project logs

Enjoy this project?

Share

Discussions

Rich text editor

Yann Guidon / YGDES wrote 04/12/2025 at 01:18 point

Something else to ponder

https://gustedt.wordpress.com/2025/01/06/simple-defer-ready-to-use/

and

https://omeranson.github.io/blog/2022/06/12/cleanup-attribute-in-C

  Are you sure? yes | no

Yann Guidon / YGDES wrote 11/15/2024 at 02:15 point

So it was all Edsgar Dijkstra's fault !
https://www.youtube.com/watch?v=2vBVvQTTdXg

https://ics.uci.edu/~jajones/INF102-S18/readings/07_dijkstra.pdf
Dijkstra, E.W. (1960) Recursive Programming. Num. Mathematik, 2, 312-. 318.

https://dijkstrascry.com/sites/default/files/papers/preprint_0.pdf

" Dijkstra’s Rallying Cry for Generalization: The Advent of the Recursive Procedure, late 1950s — early 1960s" Edgar G. Daylight Autumn, 2010


  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates