Thread: I can't spot my mistake...

  1. #31
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by Hodor View Post
    Yeah it built libalu_d.so ok (it's in the directory); it's not linking though

    Code:
    $ ls
    1st.mak      alu.h        alu_int_d.o   alu_math_d.o  alu_uint_d.o  cloned       libalu_d.so  test_d.o
    GNUmakefile  alu_bit.c    alu_main.c    alu_mem.c     alu_vec.c     dst_cc.mak   main.mak
    LICENSE      alu_bit_d.o  alu_main_d.o  alu_mem_d.o   alu_vec_d.o   dst_sys.mak  makefile
    README.md    alu_int.c    alu_math.c    alu_uint.c    char.mak      func.mak     test.c
    AH! Just a thought, try removing the 'lib' part from the library name, maybe your system doesn't prepend that when searching

  2. #32
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    I add
    Code:
    .LIBPATTERNS:=$(DST_LIB_PFX)%.$(DST_LIB_SFX) $(DST_LIB_PFX)%.a
    to the dst_sys.mak header so that should reduce linkage errors

  3. #33
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Managed to fix the issue with register acquisition but now encountering a stack smashing fault, I don't know how to look for the cause of that so I would appreciate suggestions, the only info I currently have from debugging is the function it occurs in and the last value printed
    Code:
    char *pos_int[] = {
    	"123",
    	"+145",
    	"0xA",
    	"0b1",
    NULL };
    
    char *neg_int[] = {
    	"-123",
    	"-0xA",
    	"-0b1", // This is the last value printed
    NULL };
    
    char *pos_fpn[] = {
    	"0",
    	"1",
    	"1.0",
    	"0.1",
    	"1.1",
    	"1e+10",
    	"1.0e+10",
    	"0.1e+10",
    	"1.1e+10",
    	"1e-10",
    	"1.0e-10",
    	"0.1e-10",
    	"1.1e-10",
    	"0xA",
    	"0xA.0",
    	"0x0.A",
    	"0xA.A",
    	"0xAp+10",
    	"0xA.0p+10",
    	"0x0.Ap+10",
    	"0xA.Ap+10",
    	"0xAp-10",
    	"0xA.0p-10",
    	"0x0.Ap-10",
    	"0xA.Ap-10",
    	"0b1",
    	"0b1.0",
    	"0b0.1",
    	"0b1.1",
    	"0b1e+10",
    	"0b1.0e+10",
    	"0b0.1e+10",
    	"0b1.1e+10",
    	"0b1e-10",
    	"0b1.0e-10",
    	"0b0.1e-10",
    	"0b1.1e-10",
    NULL };
    
    char *neg_fpn[] = {
    	"-0.0",
    	"-1",
    	"-1.0",
    	"-0.1",
    	"-1.1",
    	"-1e+10",
    	"-1.0e+10",
    	"-0.1e+10",
    	"-1.1e+10",
    	"-1e-10",
    	"-1.0e-10",
    	"-0.1e-10",
    	"-1.1e-10",
    	"-0xA",
    	"-0xA.0",
    	"-0x0.A",
    	"-0xA.A",
    	"-0xAp+10",
    	"-0xA.0p+10",
    	"-0x0.Ap+10",
    	"-0xA.Ap+10",
    	"-0xAp-10",
    	"-0xA.0p-10",
    	"-0x0.Ap-10",
    	"-0xA.Ap-10",
    	"-0b1",
    	"-0b1.0",
    	"-0b0.1",
    	"-0b1.1",
    	"-0b1e+10",
    	"-0b1.0e+10",
    	"-0b0.1e+10",
    	"-0b1.1e+10",
    	"-0b1e-10",
    	"-0b1.0e-10",
    	"-0b0.1e-10",
    	"-0b1.1e-10",
    NULL };
    
    int print_value( alu_t *alu, bool print_anyways )
    {
    	int ret = 0, i;
    	alu_src_t _src = {NULL};
    	alu_dst_t _dst = {NULL};
    	alu_base_t base = {0};
    	alu_lit_t lit = {0};
    	alu_block_t __src = {0}, __dst = {0};
    	char *src;
    	size_t size;
    	long nextpos;
    	
    	base.digsep = '\'';
    	base.base = 10;
    	ret = alu_get_reg_nodes( alu, base.regv, ALU_BASE_COUNT, 0 );
    	
    	
    	if ( ret != 0 )
    	{
    		alu_error( ret );
    		return ret;
    	}
    	
    	ret = alu_get_reg_nodes( alu, lit.regv, ALU_LIT_COUNT, 0 );
    	
    	
    	if ( ret != 0 )
    	{
    		alu_rem_reg_nodes( alu, base.regv, ALU_BASE_COUNT );
    		alu_error( ret );
    		return ret;
    	}
    	
    	_src.src = &__src;
    	_src.next = (alu_func_rdChar32_t)func_rdChar32;
    	_src.nextpos = &nextpos;
    	
    	_dst.dst = &__dst;
    	_dst.next = (alu_func_wrChar32_t)func_wrChar32;
    	_dst.flip = (alu_func_flipstr_t)func_flipstr;
    	
    	for ( i = 0; pos_int[i]; ++i )
    	{
    		src = pos_int[i];
    		size = strlen(src);
    		switch ( src[1] )
    		{
    		case 'x': case 'X': base.base = 16; break;
    		case 'b': case 'B': base.base = 2; break;
    		default: base.base = 10;
    		}
    		
    		nextpos = 0;
    		__src.block = src;
    		__src.bytes.used = strlen(src);
    		__src.bytes.last = __src.bytes.used;
    		__src.bytes.upto = size ? size : __src.bytes.used + 1;
    		
    		ret = alu_block_expand( &__dst, __src.bytes.upto * 2 );
    		if ( ret != 0 )
    			return ret;
    		
    		ret = reg_print_value( alu, _src, _dst, base, lit, print_anyways );
    		
    		
    		if ( ret != 0 )
    		{
    			alu_error( ret );
    			goto fail;
    		}
    		
    		ret = uint_print_value( alu, _src, _dst, base, lit, print_anyways );
    		
    		
    		if ( ret != 0 )
    		{
    			alu_error( ret );
    			goto fail;
    		}
    		
    		ret = int_print_value( alu, _src, _dst, base, lit, print_anyways );
    		
    		
    		if ( ret != 0 )
    		{
    			alu_error( ret );
    			goto fail;
    		}
    	}
    	
    	for ( i = 0; neg_int[i]; ++i )
    	{
    		src = neg_int[i];
    		size = strlen(src);
    		switch ( src[1] )
    		{
    		case 'x': case 'X': base.base = 16; break;
    		case 'b': case 'B': base.base = 2; break;
    		default: base.base = 10;
    		}
    		
    		nextpos = 0;
    		__src.block = src;
    		__src.bytes.used = strlen(src);
    		__src.bytes.last = __src.bytes.used;
    		__src.bytes.upto = size ? size : __src.bytes.used + 1;
    		
    		ret = alu_block_expand( &__dst, __src.bytes.upto * 2 );
    		
    		if ( ret != 0 )
    		{
    			alu_error( ret );
    			goto fail;
    		}
    		
    		ret = int_print_value( alu, _src, _dst, base, lit, print_anyways );
    		
    		
    		if ( ret != 0 )
    		{
    			alu_error( ret );
    			goto fail;
    		}
    	}
    	
    	fail:
    	alu_block_release( &__dst );
    	return ret;
    }
    Sorry Hodor, still further no ideas on your failed linkage issue, if what I suggested and did don't fix it then you'll just have to try what ever you think of, at the most you'll only be editing the *.mak files so that should at least reduce the annoyance if you care enough to try. Let me know how it goes if you do try and even if you don't at least let me know if it's a lost cause trying to get you to compile it again.

  4. #34
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    As it turns out the stack smashing appears to actually be in main(), tried moving the call to later on and tried seeing what other group tests did, it still reported stack smashing, from what little research I did on stack smashing I can't see any particular reason for it to occur unless I misunderstood something, here's what main looks like:
    Code:
    int main()
    {
    	int ret = 0;
    	uint_t preallocate = 32;
    	//uint_t seed = time(NULL);
    	bool print_anyways = false;
    	
    	alu_t _alu = {0}, *alu = &_alu;
    	
    	//print_limits();
    
    	alu_printf( "Pre-allocating %u ALU registers...", preallocate );
    	ret = alu_setup_reg( alu, preallocate, 0, 0 );
    	
    	if ( ret != 0 )
    	{
    		alu_error( ret );
    		return EXIT_FAILURE;
    	}
    
    #if 1
    	ret = compare( alu, print_anyways );
    	
    	if ( ret != 0 )
    	{
    		alu_error( ret );
    		goto fail;
    	}
    #endif
    
    #if 0
    	ret = bitwise( alu, true, true, print_anyways );
    	
    	if ( ret != 0 )
    	{
    		alu_error( ret );
    		goto fail;
    	}
    #endif
    
    #if 0
    	ret = mathmatical( alu, false, true, print_anyways );
    	
    	if ( ret != 0 )
    	{
    		alu_error( ret );
    		goto fail;
    	}
    #endif
    
    	ret = print_value( alu, true );
    	
    	if ( ret != 0 )
    	{
    		alu_error( ret );
    		goto fail;
    	}
    	
    #if 0
    	for ( num = 0; num < 0x10; ++num )
    		alu_printf( "%u", (seed = rng(seed)) );
    #endif
    
    	if ( ret != 0 )
    		alu_error( ret );
    		
    		
    	fail:
    	
    	(void)alu_vec_shrink( alu, 0, 0 );
    	(void)memset( alu, 0, sizeof(alu_t) );
    	
    	return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
    }
    Any ideas? Reminder of code source: GitHub - awsdert/alu: Library modeled after the Arithmetic Logic Unit built into CPUs

  5. #35
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    Hi,

    I did clone your repo, and tried building it with just "make" and had no success:

    Code:
    ....
    test.c:(.text+0x4529): undefined reference to `alu_str2int'
    test.c:(.text+0x45c7): undefined reference to `alu_int2str'
    test.c:(.text+0x46a3): undefined reference to `alu_rem_reg_node'
    test.o: In function `print_value':
    test.c:(.text+0x48d4): undefined reference to `alu_block'
    test.c:(.text+0x4c22): undefined reference to `alu_block'
    test.c:(.text+0x4d78): undefined reference to `alu_block'
    test.o: In function `main':
    test.c:(.text+0x4e55): undefined reference to `alu_setup_reg'
    test.c:(.text+0x4ffc): undefined reference to `alu_vec'
    collect2: error: ld returned 1 exit status
    main.mak:91: recipe for target 'alu.AppImage' failed
    make[3]: *** [alu.AppImage] Error 1
    1st.mak:6: recipe for target 'build' failed
    make[2]: *** [build] Error 2
    main.mak:68: recipe for target 'all' failed
    make[1]: *** [all] Error 2
    1st.mak:6: recipe for target 'all' failed
    make: *** [all] Error 2
    So I short-cut it all:

    Code:
    ~/alu$ gcc -o alu *.c -I cloned/fbstdc/include
    ~/alu$
    I now also get your issue:

    Code:
    :~/alu$ ./alu
    test.c:1341: main() Pre-allocating 32 ALU registers...
    test.c:698: compare() 'Comparing values...'
    test.c:699: compare() '==========================================='
    *** stack smashing detected ***: <unknown> terminated
    Aborted (core dumped)
    So now I compiled with warnings turned up to 11:

    Code:
    gcc -o alu *.c -I cloned/fbstdc/include -Wall -pedantic -O4
    I get 556 lines of warning where dodgy stuff is going on. You really want to fix all of thoses before you start any serious debugging.

    But seriously: I'm more then willing to help you get this into shape, but do you really want my help?

    I do know a bit of this stuff - if you want, have a look at my toy RISCV RV32I CPU's ALU.

    Rudi-RV32I/alu.vhd at master * hamsternz/Rudi-RV32I * GitHub
    Last edited by hamster_nz; 09-15-2020 at 04:15 PM.

  6. #36
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by hamster_nz View Post
    Hi,

    I did clone your repo, and tried building it with just "make" and had no success:

    Code:
    ....
    test.c:(.text+0x4529): undefined reference to `alu_str2int'
    test.c:(.text+0x45c7): undefined reference to `alu_int2str'
    test.c:(.text+0x46a3): undefined reference to `alu_rem_reg_node'
    test.o: In function `print_value':
    test.c:(.text+0x48d4): undefined reference to `alu_block'
    test.c:(.text+0x4c22): undefined reference to `alu_block'
    test.c:(.text+0x4d78): undefined reference to `alu_block'
    test.o: In function `main':
    test.c:(.text+0x4e55): undefined reference to `alu_setup_reg'
    test.c:(.text+0x4ffc): undefined reference to `alu_vec'
    collect2: error: ld returned 1 exit status
    main.mak:91: recipe for target 'alu.AppImage' failed
    make[3]: *** [alu.AppImage] Error 1
    1st.mak:6: recipe for target 'build' failed
    make[2]: *** [build] Error 2
    main.mak:68: recipe for target 'all' failed
    make[1]: *** [all] Error 2
    1st.mak:6: recipe for target 'all' failed
    make: *** [all] Error 2
    So I short-cut it all:

    Code:
    ~/alu$ gcc -o alu *.c -I cloned/fbstdc/include
    ~/alu$
    I now also get your issue:

    Code:
    :~/alu$ ./alu
    test.c:1341: main() Pre-allocating 32 ALU registers...
    test.c:698: compare() 'Comparing values...'
    test.c:699: compare() '==========================================='
    *** stack smashing detected ***: <unknown> terminated
    Aborted (core dumped)
    So now I compiled with warnings turned up to 11:

    Code:
    gcc -o alu *.c -I cloned/fbstdc/include -Wall -pedantic -O4
    I get 556 lines of warning where dodgy stuff is going on. You really want to fix all of thoses before you start any serious debugging.

    But seriously: I'm more then willing to help you get this into shape, but do you really want my help?

    I do know a bit of this stuff - if you want, have a look at my toy RISCV RV32I CPU's ALU.

    Rudi-RV32I/alu.vhd at master * hamsternz/Rudi-RV32I * GitHub
    I actually forgot that flag existed, considering the type of project it is there's no real reason for me to not add it in and leave it there permanently, already helping me identify a bunch of bugs introduced while I was changing the core API, dealing with them now, some on the other hand are minor and safe to ignore (fixing 'em anyways though)

  7. #37
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    I stripped your test code back to the bare minimum, and it still fails:

    Code:
    
    int main()
    {
            int ret = 0;
            uint_t preallocate = 32;
            //uint_t seed = time(NULL);
            bool print_anyways = false;
    
    
            alu_t alu;
    
    
            //print_limits();
    
    
            alu_printf( "Pre-allocating %u ALU registers...", preallocate );
            ret = alu_setup_reg( &alu, preallocate, 0, 0 );
    
    
            if ( ret != 0 )
            {
                    alu_error( ret );
                    return EXIT_FAILURE;
            }
            return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
    }
    Here's the result - the heap is being corrupted:

    Code:
    ~/alu$ ./alu
    test.c:1341: main() Pre-allocating 32 ALU registers...
    alu: malloc.c:2868: mremap_chunk: Assertion `((size + offset) & (GLRO (dl_pagesize) - 1)) == 0' failed.
    Aborted (core dumped)
    Why all the complexity around managing alu_block?

    Code:
    int_t alu_block( struct alu_block *mem, size_t want, int_t dir );
    # define alu_block_expand( MEM, WANT ) alu_block( MEM, WANT, 1 )
    # define alu_block_shrink( MEM, WANT ) alu_block( MEM, WANT, -1 )
    # define alu_block_release( MEM ) (void)alu_block( MEM, 0, -1 )
    Shouldn't the interface just be:

    int_t alu_block( struct alu_block *mem, size_t want)

    What advantages does knowing if you are expanding or shrinking give you? won't alu_block be able to infer what you are attempting to do?
    Last edited by hamster_nz; 09-15-2020 at 04:33 PM.

  8. #38
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by hamster_nz View Post
    I stripped your test code back to the bare minimum, and it still fails:

    Code:
    
    int main()
    {
            int ret = 0;
            uint_t preallocate = 32;
            //uint_t seed = time(NULL);
            bool print_anyways = false;
    
    
            alu_t alu;
    
    
            //print_limits();
    
    
            alu_printf( "Pre-allocating %u ALU registers...", preallocate );
            ret = alu_setup_reg( &alu, preallocate, 0, 0 );
    
    
            if ( ret != 0 )
            {
                    alu_error( ret );
                    return EXIT_FAILURE;
            }
            return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
    }
    Here's the result - the heap is being corrupted:

    Code:
    ~/alu$ ./alu
    test.c:1341: main() Pre-allocating 32 ALU registers...
    alu: malloc.c:2868: mremap_chunk: Assertion `((size + offset) & (GLRO (dl_pagesize) - 1)) == 0' failed.
    Aborted (core dumped)
    Why all the complexity around managing alu_block?

    Code:
    int_t alu_block( struct alu_block *mem, size_t want, int_t dir );
    # define alu_block_expand( MEM, WANT ) alu_block( MEM, WANT, 1 )
    # define alu_block_shrink( MEM, WANT ) alu_block( MEM, WANT, -1 )
    # define alu_block_release( MEM ) (void)alu_block( MEM, 0, -1 )
    Shouldn't the interface just be:

    int_t alu_block( struct alu_block *mem, size_t want)

    What advantages does knowing if you are expanding or shrinking give you? won't alu_block be able to infer what you are attempting to do?
    Knowing allows it to determine when it should actually fail, for example the bytes wanted could have been corrupted and given a smaller than desired size, in such a case it just pretends it reallocated and just leaves the memory as is, in reverse situation (more bytes than wanted) it deliberately fails, only passes onto reallocate if the wanted bytes matches the direction (or when no specific direction given), it's just a convenience to have all the checks be done in one function, the only reason for the defines is for readability

    Edit: btw just uploaded the fixes for the -pedantic related stuff, still got no further ideas on why the linkage failed (all the functions are mainly in alu_main.c or alu_math.c, rest are wrappers or further abstractions)
    Edit 2: Gonna catch some shut eye now, I'll check 2mw to see if you came up with any ideas that I haven't (like that -pedantic switch)
    Last edited by awsdert; 09-15-2020 at 04:46 PM.

  9. #39
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    OK, found an issue for you.

    In alu_main.c, int_t alu_get_reg_node is what is smashing your stack.

    The parameter "dest" is a pointer to "uint_t", but then you clear it out with "(void)memset( dst, 0, sizeof(alu_reg_t) );"

    If sizeof(alu_reg_t) is larger than sizeof(uint_t), it will smash your stack.



    Also in alu_get_reg_nodes(), this is pretty shabby pattern to use:

    Code:
                           count *= (ret == 0);
    at least replace it with:


    Code:
                           if(ret != 0) {
                              break;
                           }
    Technically it works, but it is very fuggy.

    Output is:
    Code:
    test.c:1333: main() Pre-allocating 32 ALU registers...
    test.c:690: compare() 'Comparing values...'
    test.c:691: compare() '==========================================='
    test.c:136: reg_compare() 0x0000000000000000 vs 0x0000000000000001 Expected -1, Got 0, Bit = 0
    
    
    test.c:137: reg_compare() num.node = 9, val.node = 9
    num = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
    val = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
    test.c:48: uint_compare() 2 vs 1 Expected 1, Got 0
    
    
    test.c:48: uint_compare() 0 vs 1 Expected -1, Got 0
    
    
    test.c:92: int_compare() 1 vs 0 Expected 1, Got 0
    
    
    test.c:92: int_compare() -1 vs 0 Expected -1, Got 0
    Last edited by hamster_nz; 09-15-2020 at 06:12 PM.

  10. #40
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by hamster_nz View Post
    OK, found an issue for you.

    In alu_main.c, int_t alu_get_reg_node is what is smashing your stack.

    The parameter "dest" is a pointer to "uint_t", but then you clear it out with "(void)memset( dst, 0, sizeof(alu_reg_t) );"

    If sizeof(alu_reg_t) is larger than sizeof(uint_t), it will smash your stack.
    AH! So that was it, I didn't even notice I left that relic there


    Quote Originally Posted by hamster_nz View Post
    Also in alu_get_reg_nodes(), this is pretty shabby pattern to use:

    Code:
                           count *= (ret == 0);
    at least replace it with:


    Code:
                           if(ret != 0) {
                              break;
                           }
    Technically it works, but it is very fuggy.
    Yeah I used that to avoid branching, bignum math is naturally slower than hardware so I use tricks like that to avoid branching since I've watched various videos about how CPUs work I realized that branching would be slower than just using the nature of multiplication and booleans to zero out an existing branch value thereby allowing the loop to run at it's maximum speed, I use tricks like that all over the place to avoid branching, the same applies to those alu_reg.node %= alu_used( alu ) statements, as long as not feeding corrupted node values then that is just a minor loss compared to branching, if the nodes are corrupted then it will be seen in corrupted results (ignoring the current situation below where an API change caused it to misunderstand information - of which I will be fixing next)

    Quote Originally Posted by hamster_nz View Post
    Output is:
    Code:
    test.c:1333: main() Pre-allocating 32 ALU registers...
    test.c:690: compare() 'Comparing values...'
    test.c:691: compare() '==========================================='
    test.c:136: reg_compare() 0x0000000000000000 vs 0x0000000000000001 Expected -1, Got 0, Bit = 0
    
    
    test.c:137: reg_compare() num.node = 9, val.node = 9
    num = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
    val = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
    test.c:48: uint_compare() 2 vs 1 Expected 1, Got 0
    
    
    test.c:48: uint_compare() 0 vs 1 Expected -1, Got 0
    
    
    test.c:92: int_compare() 1 vs 0 Expected 1, Got 0
    
    
    test.c:92: int_compare() -1 vs 0 Expected -1, Got 0

  11. #41
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Thought I fixed this damn bug, getting corrupted node values again:
    Code:
    make run
    MAKECMDGOALS=run
    make -j 1 --no-print-directory -f main.mak run
    PRJ_SRC_FILES = 'test.c alu_bit.c alu_int.c alu_main.c alu_math.c alu_mem.c alu_uint.c alu_vec.c'
    Checking 3rd Party libraries are upto date
    cd 'cloned/fbstdc' && git config pull.rebase true && git pull
    Already up to date.
    Finished checking
    PRJ_DST_BIN=alu.AppImage
    PRJ_DST_LIB=libalu.so
    ./alu.AppImage
    test.c:1344: main() Pre-allocating 32 ALU registers...
    test.c:701: compare() 'Comparing values...'
    test.c:702: compare() '==========================================='
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 8, r = 8
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 9, r = 8
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 9, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    test.c:122: reg_compare() 1: num.node = 8, val.node = 9
    test.c:126: reg_compare() 2: num.node = 8, val.node = 9
    test.c:130: reg_compare() 3: num.node = 8, val.node = 9
    test.c:140: reg_compare() 4: num.node = 8, val.node = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    test.c:122: reg_compare() 1: num.node = 9, val.node = 9
    test.c:126: reg_compare() 2: num.node = 9, val.node = 9
    test.c:130: reg_compare() 3: num.node = 9, val.node = 9
    test.c:140: reg_compare() 4: num.node = 9, val.node = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    test.c:122: reg_compare() 1: num.node = 9, val.node = 9
    test.c:126: reg_compare() 2: num.node = 9, val.node = 9
    test.c:130: reg_compare() 3: num.node = 9, val.node = 9
    test.c:140: reg_compare() 4: num.node = 9, val.node = 9
    test.c:144: reg_compare() 0x0000000000000000 vs 0x0000000000000001 Expected -1, Got 0, Bit = 0
    test.c:148: reg_compare() 5: num.node = 9, val.node = 9
    num = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
    val = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    test.c:46: uint_compare() 2 vs 1 Expected 1, Got 0
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    test.c:46: uint_compare() 0 vs 1 Expected -1, Got 0
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    test.c:90: int_compare() 1 vs 0 Expected 1, Got 0
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    test.c:90: int_compare() -1 vs 0 Expected -1, Got 0
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    test.c:986: reg_print_value() 'Testing alu_lit2reg() & alu_reg2str()'
    test.c:987: reg_print_value() '-------------------------------------'
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:191: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:193: alu_get_reg_node() alu_used( alu ) = 10, r = 9
    alu_main.c:965: alu_reg2str() Error 0x00000059 89 'Destination address required'
    alu_main.c:46: alu_print_reg() src: node = 9, part = 0x5571a0a60408, from = 0, upto = 320
    alu_main.c:8: alu_print_info() Checking src.info for flags:
    alu_main.c:10: alu_print_info() alu_reg_active( alu, src ), has this flag?... No
    alu_main.c:18: alu_print_info() alu_reg_signed( alu, src ), has this flag?... No
    alu_main.c:27: alu_print_info() alu_reg_floating( alu, src ), has this flag?... No
    test.c:1018: reg_print_value() Error 0x00000059 89 'Destination address required'
    test.c:1022: reg_print_value() Expected = '123', Got = '123'
    test.c:1269: print_value() Error 0x00000059 89 'Destination address required'
    test.c:1387: main() Error 0x00000059 89 'Destination address required'
    make[1]: *** [main.mak:79: run] Error 1
    make: *** [1st.mak:6: run] Error 2
    Compilation failed.
    This is the only place I can fathom there being an issue:
    Code:
    int_t alu_setup_reg( alu_t *alu, uint_t want, uint_t used, size_t perN )
    {
    	int ret;
    	uint_t i;
    	
    	if ( alu )
    	{
    		want = HIGHEST( want, ALU_REG_ID_NEED );
    		want = LOWEST( want, ALU_REG_ID_LIMIT );
    		used = LOWEST( want, HIGHEST( used, ALU_REG_ID_NEED ) );
    		
    		perN = HIGHEST( perN, want );
    		perN += LOWEST
    		(
    			sizeof(size_t)
    			, sizeof(size_t) - (perN % sizeof(size_t))
    		);
    		
    		ret = alu_vec_expand( alu, want, perN );
    		
    		if ( ret == 0 )
    		{
    			alu_set_used( alu, used );
    			
    			for ( i = 0; i < ALU_REG_ID_NEED; ++i )
    			{
    				alu_active( alu, i ) = true;
    			}
    			
    			alu_set_constants( alu );
    			return 0;
    		}
    		
    		alu_error( ret );
    		return ret;
    	}
    	
    	return alu_err_null_ptr( "alu" );
    }
    
    int_t alu_get_reg_node( alu_t *alu, uint_t *dst, size_t need )
    {
    	int ret;
    	uint_t count = 0, r = count;
    	void *part;
    	
    	if ( alu )
    	{
    		if ( dst )
    		{
    			*dst = 0;
    			
    			need = HIGHEST( need, alu_size_perN( alu ) );
    			count = alu_used( alu );
    			
    			for ( r = ALU_REG_ID_NEED; r < count; ++r )
    			{
    				count = SET1IF( alu_active( alu, r ), count );
    			}
    			
    			count = alu_used( alu );
    			
    			if ( r >= alu_upto( alu ) || need > alu_size_perN( alu ) )
    			{
    				count = HIGHEST( r + 1, alu_upto( alu ) );
    				ret = alu_setup_reg( alu, count, count, need );
    					
    				if ( ret != 0 )
    				{
    					alu_error( ret );
    					return ret;
    				}
    			}
    			
    			alu_printf( "alu_used( alu ) = %u, r = %u", alu_used( alu ), r );
    			alu_used( alu ) = HIGHEST( r + 1, count );
    			alu_printf( "alu_used( alu ) = %u, r = %u", alu_used( alu ), r );
    			
    			part = alu_data( alu, r );
    			(void)memset( part, 0, need );
    			
    			alu_active( alu, r ) = true;
    			
    			*dst = r;
    			
    			return 0;
    		}
    		
    		return alu_err_null_ptr( "dst" );		
    	}
    	
    	return alu_err_null_ptr( "alu" );
    }
    
    int_t alu_rem_reg_nodes( alu_t *alu, uint_t *nodes, int count )
    {	
    	if ( alu )
    	{
    		if ( nodes )
    		{		
    			for ( --count; count >= 0; --count )
    			{
    				alu_rem_reg_node( alu, nodes + count );
    			}
    			
    			return 0;
    		}
    		
    		return alu_err_null_ptr( "nodes" );
    	}
    	
    	return alu_err_null_ptr( "alu" );
    }
    
    int_t alu_get_reg_nodes( alu_t *alu, uint_t *nodes, uint_t count, size_t need )
    {
    	int ret = 0;
    	uint_t r;
    	uint_t *dst;
    	
    	if ( alu )
    	{
    		for ( r = 0; r < count; ++r )
    		{
    			dst = nodes + r;
    				
    			ret = alu_get_reg_node( alu, dst, need );
    			count *= (ret == 0);
    		}
    		
    		if ( ret != 0 )
    		{
    			alu_error( ret );
    			alu_rem_reg_nodes( alu, nodes, r );
    		}
    		
    		return ret;
    	}
    	
    	return alu_err_null_ptr( "alu" );
    }
    Any ideas? Reminder full code: GitHub - awsdert/alu: Library modeled after the Arithmetic Logic Unit built into CPUs

  12. #42
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    As I don't know your code or the problem you are solving , so I can't tell what you know is not right.

    What seems to be the problem? and what would you expect the correct output would be? What should be happening but isn't?

  13. #43
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    Found why it won't link.

    At least on my toolchain (gcc 7.5.0) the "-l alu" needs to be after the "test.o"

    I've done the following in main.mak to make it make:

    Code:
    BIN_FLAGS:=$(DBG_FLAGS) -fPIE $(COP)L . $(COP)l alu$(DBG_SFX)
    COMPILE_EXE=$(CC) $(BIN_FLAGS) $1 $(COP)o $2 $3 $(RPATH_FLAG)
    Code:
    BIN_FLAGS:=$(DBG_FLAGS) -fPIE $(COP)L . $(DBG_SFX)
     COMPILE_EXE=$(CC) $(BIN_FLAGS) $1 $(COP)o $2 $3 $(RPATH_FLAG) $(COP)l alu

  14. #44
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    I notice that you occasionally pass a few structures as parameters:

    Code:
    int_t alu_lit2reg
    (
            alu_t *alu
            , alu_src_t src
            , alu_reg_t dst
            , alu_base_t base
    )
    As this example shows, if you do this, any changes made to src, dst or base made in the function won't be seen on return to the caller:

    Code:
    #include <stdio.h>
    
    
    struct s {
      int a;
      int b;
    };
    typedef struct s s_t;
    
    
    void f(s_t test) {
       printf("On entry to f(): test.a %i  test.b %i\n", test.a, test.b);
       test.a = 10;
       test.b = 10; 
       printf("On exit from f(): test.a %i  test.b %i\n", test.a, test.b);
    }
    
    
    void g(s_t *test) {
       printf("On entry to f(): test.a %i  test.b %i\n", test->a, test->b);
       test->a = 10;
       test->b = 10; 
       printf("On exit from f(): test.a %i  test.b %i\n", test->a, test->b);
    }
    
    
    int main(int argc, char *argv[]) {
       s_t test;
       test.a = 1;
       test.b = 1;
    
    
       f(test);
       printf("On return to main():  test.a %i  test.b %i\n", test.a, test.b);
       printf("\n");
    
    
       g(&test);
       printf("On return to main():  test.a %i  test.b %i\n", test.a, test.b);
    }
    It's also inefficient to do this, because the structure has to be copied to the stack, rather than just passing the address.

  15. #45
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,733
    Quote Originally Posted by hamster_nz View Post
    I notice that you occasionally pass a few structures as parameters:

    Code:
    int_t alu_lit2reg
    (
            alu_t *alu
            , alu_src_t src
            , alu_reg_t dst
            , alu_base_t base
    )
    As this example shows, if you do this, any changes made to src, dst or base made in the function won't be seen on return to the caller:

    Code:
    #include <stdio.h>
    
    
    struct s {
      int a;
      int b;
    };
    typedef struct s s_t;
    
    
    void f(s_t test) {
       printf("On entry to f(): test.a %i  test.b %i\n", test.a, test.b);
       test.a = 10;
       test.b = 10; 
       printf("On exit from f(): test.a %i  test.b %i\n", test.a, test.b);
    }
    
    
    void g(s_t *test) {
       printf("On entry to f(): test.a %i  test.b %i\n", test->a, test->b);
       test->a = 10;
       test->b = 10; 
       printf("On exit from f(): test.a %i  test.b %i\n", test->a, test->b);
    }
    
    
    int main(int argc, char *argv[]) {
       s_t test;
       test.a = 1;
       test.b = 1;
    
    
       f(test);
       printf("On return to main():  test.a %i  test.b %i\n", test.a, test.b);
       printf("\n");
    
    
       g(&test);
       printf("On return to main():  test.a %i  test.b %i\n", test.a, test.b);
    }
    It's also inefficient to do this, because the structure has to be copied to the stack, rather than just passing the address.
    Well the 1st 2 structures (alu_src_t & alu_dst_t) hold pointers to the object that should be read from or written to and the various functions needed for interacting with them (along with a position pointer for the case of alu_src_t) so they are meant to be copied for skipping the branch that would otherwise check that 1st pointer, adding a few temporary variables would be faster than throwing away previously preloaded instructions just to load a different set, the 3rd (alu_base_t) is NEVER meant to have it's changes seen by the caller, the only change the caller should see in that scenario is the change made to *(src.nextpos) and the change made to alu_reg_data( alu, dst ), that is literally all the caller needs to see on that function, besides even if there is in error in that function I cannot track it properly as long as the node indexes are being given corrupt values.

    On another note I will make the change you suggested for the makefile regarding "-l alu" (honestly didn't expect fast reply so that is why I took a while to respond)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. can anyone help to spot mistake in the code
    By chess_queen in forum C Programming
    Replies: 1
    Last Post: 10-21-2012, 10:37 AM
  2. Can you spot my mistake?
    By Brewer in forum C Programming
    Replies: 13
    Last Post: 11-12-2006, 12:50 PM
  3. going to a certain spot in a file...
    By agerealm in forum C++ Programming
    Replies: 3
    Last Post: 05-17-2002, 02:31 AM

Tags for this Thread