SKyd3R
Posts: 11
Joined: Thu Nov 14, 2013 9:30 am

__eabi div operations

Mon Apr 28, 2014 9:31 am

Hello,

I'm trying to create a bare metal system but I have the following undefined references:
  • undefined reference to `__aeabi_idiv'
    undefined reference to `__aeabi_idivmod'
    undefined reference to `__aeabi_uidivmod'
    undefined reference to `__aeabi_uldivmod'
    undefined reference to `__aeabi_ldivmod'
I tried to include the libgcc found at brianwiddas' rpi-baremetal (https://github.com/brianwiddas/pi-baremetal) but when I compile the project I got this error:

Code: Select all

arm-eabi-ld: libgcc.a(_udivsi3.o): Unknown mandatory EABI object attribute 44
arm-eabi-ld: failed to merge target specific data of file libgcc.a(_udivsi3.o)
arm-eabi-ld: libgcc.a(_divsi3.o): Unknown mandatory EABI object attribute 44
arm-eabi-ld: failed to merge target specific data of file libgcc.a(_divsi3.o)
arm-eabi-ld: libgcc.a(_aeabi_ldivmod.o): Unknown mandatory EABI object attribute 44
arm-eabi-ld: failed to merge target specific data of file libgcc.a(_aeabi_ldivmod.o)
arm-eabi-ld: libgcc.a(_aeabi_uldivmod.o): Unknown mandatory EABI object attribute 44
arm-eabi-ld: failed to merge target specific data of file libgcc.a(_aeabi_uldivmod.o)
arm-eabi-ld: libgcc.a(_dvmd_lnx.o): Unknown mandatory EABI object attribute 44
arm-eabi-ld: failed to merge target specific data of file libgcc.a(_dvmd_lnx.o)
arm-eabi-ld: error: libgcc.a(bpabi.o) uses VFP register arguments, build/output.elf does not
arm-eabi-ld: warning: libgcc.a(bpabi.o) uses 32-bit enums yet the output is to use variable-size enums; use of enum values across objects may fail
arm-eabi-ld: libgcc.a(bpabi.o): Unknown mandatory EABI object attribute 44
arm-eabi-ld: failed to merge target specific data of file libgcc.a(bpabi.o)
arm-eabi-ld: error: libgcc.a(_divdi3.o) uses VFP register arguments, build/output.elf does not
arm-eabi-ld: warning: libgcc.a(_divdi3.o) uses 32-bit enums yet the output is to use variable-size enums; use of enum values across objects may fail
arm-eabi-ld: libgcc.a(_divdi3.o): Unknown mandatory EABI object attribute 44
arm-eabi-ld: failed to merge target specific data of file libgcc.a(_divdi3.o)
arm-eabi-ld: error: libgcc.a(_udivdi3.o) uses VFP register arguments, build/output.elf does not
arm-eabi-ld: warning: libgcc.a(_udivdi3.o) uses 32-bit enums yet the output is to use variable-size enums; use of enum values across objects may fail
arm-eabi-ld: libgcc.a(_udivdi3.o): Unknown mandatory EABI object attribute 44
arm-eabi-ld: failed to merge target specific data of file libgcc.a(_udivdi3.o)
libgcc.a(_dvmd_lnx.o): In function `__aeabi_ldiv0':
(.text+0x8): undefined reference to `raise'
make: *** [build/output.elf] Error 1
I'm using an arm-eabi compiler supplied here http://www.dit.upm.es/~str/proyectos/mi ... index.html.

I could run several things (program and handle timer interrupts, my own printf library for hdmi or serial port) until I start with divisions and modules. I'm trying to build my own library but I think there should be a way to use one already built and optimized.

Thanks a lot for your time.

dwelch67
Posts: 955
Joined: Sat May 26, 2012 5:32 pm

Re: __eabi div operations

Mon Apr 28, 2014 1:30 pm

That is so annoying when that happens isnt it? Sometimes it does, sometimes it inserts them for you.

In any case get the sources for gcc, inside are the gcc libraries of which are those divide functions. There are a lot of defines and such so the code is difficult to use as is. My ugly trick is to put a syntax error in one of the files or something like that then build gcc, when it hits that file it leaves the full command line on the terminal. And there you go, take the command line take the gcc library functions in question, and make your own if you cant get them to link in.

Yes in theory the non-linux eabi toolchain should properly link in the gcc library files. Why sometimes it does and sometimes it doesnt is a mystery or at least a curiosity. I would love to see a solution that leads to 100% success.

David

tgritchie
Posts: 19
Joined: Fri Jun 01, 2012 4:07 pm
Location: United Kingdom

Re: __eabi div operations

Sat May 03, 2014 9:22 am

In researching my pure assembler bare metal project I discovered this macro definition of a 32-bit integer division which could relatively easily be called from C code:

Code: Select all

@ Software simulation of 32 bit unsigned integer division
@ Entry  r0: numerator (lo) must be signed positive
@		r6: denominator (den) must be non-zero and signed negative
		lo .req r0; hi .req r5; den .req r6
idiv0:
	mov hi, #0 @ hi = 0
	adds lo, lo, lo
	.rept 32 @ repeat 32 times
	  adcs hi, den, hi, lsl #1
	  subcc hi, hi, den
	  adcs lo, lo, lo
	.endr
	mov pc, lr
The register allocations are of course arbitrary. You can pick any to suit your application

SKyd3R
Posts: 11
Joined: Thu Nov 14, 2013 9:30 am

Re: __eabi div operations

Wed May 07, 2014 7:50 am

Thanks for all your help. I think I managed to make the functions I need :)

If anyone need it I could upload them.

tufty
Posts: 1456
Joined: Sun Sep 11, 2011 2:32 pm

Re: __eabi div operations

Wed May 07, 2014 9:49 am

dwelch67 wrote:That is so annoying when that happens isnt it? Sometimes it does, sometimes it inserts them for you.
There's a whole lot of wrong in that gcc output, and it's far from arbitrary.

Firstly, there's all the "Unknown EABI Attribute" stuff, which implies the toolchain doesn't match up with the libgcc that's trying to be linked (unsurprising, mixing and matching random compilers / linkers with random low-level libraries is never a good idea). Specifically, it indicates that the toolchain being used is way out of date. Building an up-to-date copy of gcc and friends would be a good idea, but it's not the easiest thing in the world to do (as you know).

Once you're past all that crap, there's object format and ABI issues. The libgcc he's trying to use uses fixed-size enums and floating point arguments, his code doesn't. That makes linking "tricksy".

And then there's a reference to function 'raise()', either he isn't linking everything required in, or he hasn't implemented raise himself. Can't remember if you're supposed to implement it yourself or not.

In any case, the solution to this is /not/ to implement the math routines yourself, but to fix your toolchain.

dwelch67
Posts: 955
Joined: Sat May 26, 2012 5:32 pm

Re: __eabi div operations

Wed May 07, 2014 5:11 pm

tufty wrote:
dwelch67 wrote:That is so annoying when that happens isnt it? Sometimes it does, sometimes it inserts them for you.
There's a whole lot of wrong in that gcc output, and it's far from arbitrary.

Firstly, there's all the "Unknown EABI Attribute" stuff, which implies the toolchain doesn't match up with the libgcc that's trying to be linked (unsurprising, mixing and matching random compilers / linkers with random low-level libraries is never a good idea). Specifically, it indicates that the toolchain being used is way out of date. Building an up-to-date copy of gcc and friends would be a good idea, but it's not the easiest thing in the world to do (as you know).

Once you're past all that crap, there's object format and ABI issues. The libgcc he's trying to use uses fixed-size enums and floating point arguments, his code doesn't. That makes linking "tricksy".

And then there's a reference to function 'raise()', either he isn't linking everything required in, or he hasn't implemented raise himself. Can't remember if you're supposed to implement it yourself or not.

In any case, the solution to this is /not/ to implement the math routines yourself, but to fix your toolchain.
Fixing the toolchain is the most painful path and a very high chance of failure.

Building the gnu tools with libgcc and a C library is not difficult at the moment, high rate of success. But you then lose that boostrap and linkerscript and other libraries that you may have been using XYZ pre-built toolchain for and have to replace those, is that more work than getting around the divide? My personal solution to making my own __eabi_div involves building a/the toolchain and then stealing from that (rather than using the toolchain I built).

I would agree that in a perfect world you shouldn't have to fix the toolchain or libraries to make your perfectly valid code:

Code: Select all

int a,b,c;
...
a = b / c;
run properly

But 1) this is bare metal embedded, 2) you get what you pay for with this toolchain...

David

tufty
Posts: 1456
Joined: Sun Sep 11, 2011 2:32 pm

Re: __eabi div operations

Wed May 07, 2014 6:19 pm

I'm afraid I have to disagree with you there, Dave. With a newly built arm-none-eabi toolchain (I built it yesterday, and the hardest bit was getting a gcc to build it with on OSX, the total time taken was about 5 minutes of active time and about 1 hour elapsed, but then I've done it before; it's known to be painful the first few times)

Code: Select all

int foo () {  
  int a = 5;
  int b = 3;
  return (a / b);
}
Compiles clean, generates code using __eabi_idiv (explicitly using -O0 to avoid the whole thing being optimised down to a single constant)

Pulling an out of date toolchain from one place and then trying to force it to use an incompatible libgcc doesn't work, unsurprisingly.

It's been my experience that that gcc and llvm toolchains, if correctly built, are remarkably solid, if not up to the code generation level of ARM, Inc's offerings. When they don't work, and particularly WRT stuff like failing to link in division primitives, it's usually operator error. In the case of the OP's original post, that's almost certainly the case.

That said, if there was one person on this forum who I'd trust when they say "you have to write your own", it's you. Just not in this case. :evil:

tgritchie
Posts: 19
Joined: Fri Jun 01, 2012 4:07 pm
Location: United Kingdom

Re: __eabi div operations

Wed May 07, 2014 7:34 pm

I tend to agree with David on this one. If you are developing in the C/C++ context, whether with or without OS support, you'd expect the gcc libraries to work *out of the box* but in the context of my current bare metal project, which is a port of pure Intel assembler to ARM, you don't have that luxury. When I was researching it I found the macro definition I posted earlier and didn't even think of the libraries as I guess I was looking for the most efficient software simulation for the inbuilt Intel IDIV instruction. However I guess the wider point is that you should choose the solution that best fits you underlying requirement. In my case this was the macro.

BTW I may not be able to avoid use of some pre-built C libraries in other areas of the project. I'm thinking here of USB keyboard support as I have tried the CSUD library of Alex Chadwick but found that it didn't work with the two keyboards I could lay my hands on. I think it is to do with the USB mode supported by the CSUD code. Does anyone know of any alternatives? Is the NOOBS bootloader code an option or is it horribly complex? I guess USB is complex period but I'd like to explore alternatives

Trevor

dwelch67
Posts: 955
Joined: Sat May 26, 2012 5:32 pm

Re: __eabi div operations

Wed May 07, 2014 9:48 pm

tufty wrote:That said, if there was one person on this forum who I'd trust when they say "you have to write your own", it's you. Just not in this case. :evil:
Hehe...thanks. Let me say this another way, I have spent so many hours in frustration trying to solve that problem and failing...That my "solutions" are 1) dont use divide at almost all costs 2) make your own divide that is somewhat independent of the toolchain. The more of my long winded drivel that you read it should make sense that my solutions will often/sometimes end up being "it hurts when I do that..." "well, dont do that".

Because I dont use divide, my build scripts might not actually work with respect to libgcc being found and linking in right, I need to make that tonights project...And I agree with what I think you are saying. From my experience it is much easier now to get binutils, gcc, and libgcc, to actually build without erroring out, and the assembler, linker, and compiler that comes out of that is more than functional for my work and habits and the things I avoid and invent myself, BUT that does not mean that toolchain is useful or even tolerable for other folks (they want libgcc, they want a C library, C++, etc). So I will try to do that tonight...actually:

Code: Select all

.globl _start
_start:
    bl fun
    b .

Code: Select all

unsigned int fun ( unsigned int a, unsigned int b )
{
    return(a/b);
}
arm-none-eabi-gcc -O2 -c fun.c -o fun.o
arm-none-eabi-as vec.s -o vec.o
arm-none-eabi-ld -Ttext=0x1000 vec.o fun.o -o fun.elf
fun.o: In function `fun':
fun.c:(.text+0x4): undefined reference to `__aeabi_uidiv'
calvin ~ #
So there we go, I failed. So this does need to be a research project...This was with
arm-none-eabi-as --version
GNU assembler (GNU Binutils) 2.24
Copyright 2013 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or later.
This program has absolutely no warranty.
This assembler was configured for a target of `arm-none-eabi'.
arm-none-eabi-gcc --version
arm-none-eabi-gcc (GCC) 4.9.0
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
actually that wasnt quite right was it adding -lgcc to the linker script didnt fix it, couldnt find -lgcc

Doing this and explicitly adding the libgcc library with a full path:

Code: Select all

arm-none-eabi-ld -Ttext=0x1000 vec.o fun.o -o fun.elf /opt/gnuarm/lib/gcc/arm-none-eabi/4.9.0/libgcc.a 
Did produce an elf file with the divide function from libgcc included in the binary. No I didnt test it this isnt a real functional program...

This works

Code: Select all

arm-none-eabi-gcc -nostartfiles -nostdlib vec.o fun.o -lgcc -o fun.elf
But that just rubs me the wrong way, you should have to use gcc to fix a linker problem, I hate that...But it worked it found libgcc and linked it in, I guess I forgot a linker script on that example.

One more thing before everyone is sick of me in this thread...replace ld with this

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main ( int argc, char *argv[] )
{
    int r;

    for(r=0;r<argc;r++) printf("[%u] [%s]\n",r,argv[r]);
    return(0);
}

Code: Select all

arm-none-eabi-gcc -nostartfiles -nostdlib vec.o fun.o -lgcc -o fun.elf
[0] [/opt/gnuarm/lib/gcc/arm-none-eabi/4.9.0/../../../../arm-none-eabi/bin/ld]
[1] [-plugin]
[2] [/opt/gnuarm/libexec/gcc/arm-none-eabi/4.9.0/liblto_plugin.so]
[3] [-plugin-opt=/opt/gnuarm/libexec/gcc/arm-none-eabi/4.9.0/lto-wrapper]
[4] [-plugin-opt=-fresolution=/tmp/ccXPNIcU.res]
[5] [-X]
[6] [-o]
[7] [fun.elf]
[8] [-L/opt/gnuarm/lib/gcc/arm-none-eabi/4.9.0]
[9] [-L/opt/gnuarm/lib/gcc/arm-none-eabi/4.9.0/../../../../arm-none-eabi/lib]
[10] [vec.o]
[11] [fun.o]
[12] [-lgcc]
basically gcc knows the path to the library and that is why it works, to do it without gcc, the way I am doing it above, you have to either put the whole path to libgcc.a or you need to add the path to the list of libraries (-L path)

dwelch67
Posts: 955
Joined: Sat May 26, 2012 5:32 pm

Re: __eabi div operations

Thu May 08, 2014 1:41 am

...here is my revised two cents...

libgcc is a gcc library so it is associated with gcc not binutils...so I guess gcc knows where it is and binutils is perhaps not expected to. maybe there is a configure thing when building binutils that says I am going to use libgcc and install it in the same place as binutils so look there for that stuff...

try this:

Code: Select all

arm-none-eabi-gcc -print-search-dirs
my result

Code: Select all

install: /opt/gnuarm/lib/gcc/arm-none-eabi/4.9.0/
programs: =/opt/gnuarm/libexec/gcc/arm-none-eabi/4.9.0/:/opt/gnuarm/libexec/gcc/arm-none-eabi/4.9.0/:/opt/gnuarm/libexec/gcc/arm-none-eabi/:/opt/gnuarm/lib/gcc/arm-none-eabi/4.9.0/:/opt/gnuarm/lib/gcc/arm-none-eabi/:/opt/gnuarm/lib/gcc/arm-none-eabi/4.9.0/../../../../arm-none-eabi/bin/arm-none-eabi/4.9.0/:/opt/gnuarm/lib/gcc/arm-none-eabi/4.9.0/../../../../arm-none-eabi/bin/
libraries: =/opt/gnuarm/lib/gcc/arm-none-eabi/4.9.0/:/opt/gnuarm/lib/gcc/arm-none-eabi/4.9.0/../../../../arm-none-eabi/lib/arm-none-eabi/4.9.0/:/opt/gnuarm/lib/gcc/arm-none-eabi/4.9.0/../../../../arm-none-eabi/lib/
and that happens to include a path to where my libgcc.a lives.

1) are you using gcc to launch the linker or the linker directly? (if the latter you may need the whole path to the dir or file)
2) is there a libgcc.a there/somewhere
3) if you can tell does the libgcc.a have the right function for the right mode (thumb vs arm or both), should get a different warning error other than undefined reference
4) if you explicitly add the entire path and filename for libgcc.a does that work
5) is the libgcc.a that works in the libraries path list of gcc -print-search-dirs?

Are you using ADA instead of gcc? (gnat?) Does gnat know what gcc knows, does it/can it print the paths and is libgcc.a there? If not then add a -L path/to/libgcc.a to your linker command line and use the linker command line.

As far as the attributes things goes I saw this when using clang with binutils to assemble and link. Newer compilers are starting to add attribute directives. In my case the assembler didnt know what to do with it until I moved to a newer binutils. In your case you have compiled code with attributes that appear to not be linking, so the disconnect appears to be between whatever generated libgcc.a and what is using (linker) libgcc.a.

Also there were VFP complaints so one or the other (the library vs the objects from your program) was built for floating point passing floating point registers an operands and the other was not, that is what I gather from the complaint there.

It seems like it chucked the whole libgcc library and the baby went out with the bath water (the one divide you were after).

I dont know enough about your toolchain or toolchains to guide further at this time examine gnat vs binutils vs the libraries, I dont if you in addition to gnat have gcc there that you can use to do the linking. I would love someday for someone to show me how to 1) build a gnat cross compiler. 2) understand the calling convention, etc in order to mix asm and ada (or C and ada or both). It is actually GHDL I am interested not bare metal gnat but I figure a rough idea of how gnat works will bridge the ghdl gap I have...

github.com/dwelch67/build_gcc is where I keep my gcc and llvm/clang build scripts for the cross compilers I use (I also use formerly codesourcery (now part of mentor graphics), free (LITE) and sometimes the pay-for, and the launchpad.net free one).

David

tufty
Posts: 1456
Joined: Sun Sep 11, 2011 2:32 pm

Re: __eabi div operations

Thu May 08, 2014 6:35 am

Bare metal GHDL? Now you're talking my kinda madness.

tufty
Posts: 1456
Joined: Sun Sep 11, 2011 2:32 pm

Re: __eabi div operations

Thu May 08, 2014 10:29 am

Also, I'd missed that the OP was using Ada. That's also my kind of madness, although it's been a /looooooong/ time since I've done any Ada.

As I'm reading it from here http://gcc.gnu.org/onlinedocs/gnat_ugn_ ... tions.html, gnat should incorporate the libgcc functions automagically, without having to resort to manually adding an external libgcc to the mix at link time. Specifically, look at the "Intrinsic" and "builtin" stuff.

dwelch67
Posts: 955
Joined: Sat May 26, 2012 5:32 pm

Re: __eabi div operations

Thu May 08, 2014 8:50 pm

Yeah, I have read that in the past..

I got this " close to getting it to work. Built 4.9.0 gnat from the apt-get install gnat (Secret is export CC=gnatgcc to avoid the you need gnat to make ada problem on debianish machines) and

Code: Select all

-- file name needs to match function
-- sum_of_numbers.ada
-- gnatgcc -c -O2 sum_of_numbers.adb -o sum_of_numbers.o

   function Sum_Of_Numbers(Val1, Val2 : INTEGER) return INTEGER is
   begin
      return Val1 + Val2;
   end Sum_Of_Numbers;
I was able to compile it to an object for the host machine which was a couple lines of code.

but either using the apt-got gnat or the built from the same sources gnat I couldnt build a cross compiler at least I gave up for now. it errored out...

David

makey
Posts: 1
Joined: Mon Jan 05, 2015 6:55 pm

Re: __eabi div operations

Mon Jan 05, 2015 7:17 pm

I had similar problem. Building for embedded ARM bare-metal but not Raspberry. This fix may be useful for others.
1. It matters in what sequence static libraries are linked, i use full path and libc.a then libgcc.a (some div functions in libgcc):

Code: Select all

LIBS += \
    $(TOOL_PATH)/$(TOOL_PREFIX)/libc/usr/lib/libc.a \
    $(TOOL_PATH)/lib/gcc/$(TOOL_PREFIX)/4.5.1/libgcc.a
2. Implement two functions to get rid of unresolved raise():

Code: Select all

int __aeabi_idiv0(int return_value)
{
    return 0;
}   
long long __aeabi_ldiv0(long long return_value)
{
    return 0;
}

Read more on this functions and their return values here: http://infocenter.arm.com/help/topic/co ... _rtabi.pdf, chapter "4.3.2 Division by zero"

Arikania
Posts: 15
Joined: Tue Sep 11, 2018 6:44 am

32-bit divisions on ARMv7-A

Sun Dec 16, 2018 12:34 pm

I use a 32-bit processor that has no built-in DIV instruction (unlike the ARMv7-R), so I designed this routine for it. It divides unsigned integers, and returns both the whole part and the remainder.

In each iteration, it finds one bit of the whole part, so the number of iterations equals the number of ones in the result's whole part. I believe this to be the fastest algorithm possible on this processor.


I hope this will benefit you all.


Code: Select all

.text
.balign 4
.type udiv, %function
.thumb_func

udiv:
  # r0		the enumerator
  # r1		the denominator


  @ at return:
  # r2		the whole part
  # r3		the remainder


  @ assumptions
  # the denominator is not 0
  # the function does not destroy its arguments or any register above r6


	# init
	movs	r2,#0
	movs	r3,r0

	# determine no. of leading bits in the denominator
	clz	r6,r1

10:	# trap 'division done'
	cmp	r3,r1

	it	lo
	bxlo	lr

	# determine preliminary shift size
	clz	r5,r3
	subs	r4,r6,r5

	# determine preliminary shifted denominator
	lsls	r5,r1,r4

	# adjust shift size and shifted denominator if the shifted denominator outranges the remainder
	cmp	r3,r5

	itt	lo
	sublo	r4,#1
	lsrlo	r5,#1

	# adjust results
	subs	r3,r5

	movs	r5,#1
	lsls	r5,r4
	orrs	r2,r5
	b	10b

This routine, in Thumb-2 code, is tested and verified.

With regards,
Arikania


May you code bravely, dear collegues :D

User avatar
Arjan
Posts: 261
Joined: Sat Sep 08, 2012 1:59 pm

Re: __eabi div operations

Sun Dec 23, 2018 5:57 pm

SKyd3R wrote:
Mon Apr 28, 2014 9:31 am
Hello,

I'm trying to create a bare metal system but I have the following undefined references:
  • undefined reference to `__aeabi_idiv'
    undefined reference to `__aeabi_idivmod'
    undefined reference to `__aeabi_uidivmod'
    undefined reference to `__aeabi_uldivmod'
    undefined reference to `__aeabi_ldivmod'
I have implemented some of the eeabi functions here -> https://github.com/vanvught/rpidmx512/t ... /src/aeabi

It is also good to check your code; Could it be possible that you can change the code in such that the div functions are not needed?
http://www.raspberrypi-dmx.org/
Open Source DMX/RDM/MIDI/OSC/Art-Net/sACN solutions

Arikania
Posts: 15
Joined: Tue Sep 11, 2018 6:44 am

Re: __eabi div operations / extra divs coming up

Mon Dec 24, 2018 11:39 am

@Arjan
The routine that I listed here above is intended as a standard routine that I can include in any project where I need it. Not every project allows divisions to be circumvented.

I intend to post a div, uldiv and ldiv function soon by the way.


@SKyd3R
The undefined reference to messages imply that those functions are in a library that you are not including in the link.

Instead of linking a whole library along with your projects though, I think that you better design your own functions for such purposes. That prevents superfluous functions being included, and allows you to control the data flows more sophisticatedly.


Kindly,

A.

Return to “Bare metal, Assembly language”