In my case the EPERM error was caused by Large Files support enabled in build configuration. It caused _FILE_OFFSET_BITS to be defined as 64 and therefore getrlimit() call became actually a getrlimit64() call, which failed (see below). Disabling Large File support fixed the issue. I'm working on an embedded ARM application, so hopefully disabling Large File support won't hurt me much.
Update half a year later:
As it turned out, I needed Large File support even on the embedded system, to be able to use mmap() with addresses > 2GB (to access hardware registers). To allow this, but still avoid calling getrlimit64 instead of getrlimit, I defined _FILE_OFFSET_BITS=64 project wide, and in the single unit where I called getrlimit, I redefined _FILE_OFFSET_BITS before including <sys/resource.h>:
#if _FILE_OFFSET_BITS == 64
# undef _FILE_OFFSET_BITS
# define _FILE_OFFSET_BITS 32
#endif
#include <sys/resource.h>
//...
//call getrlimit()
But why getrlimit64() failed with EPERM:
As per Gilles comment to the original question above, this is probably a way my libc returns "not implemented" error. See this thread for another example of the same EPERM usage.