GCC provides a low-level runtime library, libgcc.a or libgcc_s.so.1 on some platforms. GCC generates calls to routines in this library automatically, whenever it needs to perform some operation that is too complicated to emit inline code for.
Most of the routines in libgcc handle arithmetic operations that the target processor cannot perform directly. This includes integer multiply and divide on some machines, and all floating-point and fixed-point operations on other machines. libgcc also includes routines for exception handling, and a handful of miscellaneous operations.
libgcc1 exists primarily conceptually. It is the basic set of operations which can not be reasonably implemented using other operations. In the good old days libgcc1 was built using the other compiler on your system. Since these days there is generally no other compiler, most targets provide assembler code to perform the operations. For example, see config/arm/lib1funcs.asm.
libgcc2, conversely, is the set of operations which can be implemented reasonably. For example, if you have a 32-bit add instruction, it’s easy to use it to implement 64-bit addition. This code appears in gcc/libgcc2.c. On many processors it is possible to optimize using instructions which are not avaliable in C, such as add-with-carry; those optimizations are written in gcc/longlong.h.