[RFC][PATCH 0/3] readelf and libbfd: Add Extended Numbering Support for ELF

Daisuke HATAYAMA d.hatayama@jp.fujitsu.com
Mon Jan 18 00:34:00 GMT 2010


From: Ian Lance Taylor <iant@google.com>
Subject: Re: [RFC][PATCH 0/3] readelf and libbfd: Add Extended Numbering Support for ELF
Date: Fri, 15 Jan 2010 07:53:26 -0800

> Daisuke HATAYAMA <d.hatayama@jp.fujitsu.com> writes:
> 
>> Extended Numbering is an ELF extension specified in order to cover a
>> lack of field size for some fields of ELF header. Concretely, they are
>> e_phnum, e_shnum and e_shstrndx, which have only 4 byte length in
>> either 32- or 64-bit environments.
> 
> You mean that they currently have a 2 byte length.
> 

Yes, you are right. The three fields have _2-byte_ length
respectively.

> I very sincerely hope that we never have an ELF file with more than
> 4,294,967,295 segments.
> 
> It's hard enough to understand having more than 65,535 segments
> (sections, sure; segments?).
> 
> Ian

Sorry, my explanation was not sufficient.

Program headers consist mainly of mmaps, so there is possibility of
program headers exceeding 65535. If you google MAX_MAP_COUNT, then
you'll find people facing the same problem.

Here is a small program, which works well at least on Linux, that is
useful to create the corefile with many program headers.

Usage:

Type as follows:

$ ulimit -c unlimited
$ sysctl vm.max_map_count=70000 # default 65530 is too small
$ sysctl fs.file-max=70000
$ mkmmaps 65535

Then, the program will abort and a corefile will be generated.

If failed, there are two cases according to the error message
displayed.

* ``out of memory'' means vm.max_map_count is still smaller

* ``too many open files'' means fs.file-max is still smaller

So, please change it to a larger value, and then retry it.

mkmmaps.c
==
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char **argv)
{
	int maps_num;
	if (argc < 2) {
		fprintf(stderr, "mkmmaps [number of maps to be created]\n");
		exit(1);
	}
	if (sscanf(argv[1], "%d", &maps_num) == EOF) {
		perror("sscanf");
		exit(2);
	}
	if (maps_num < 0) {
		fprintf(stderr, "%d is invalid\n", maps_num);
		exit(3);
	}
	for (; maps_num > 0; --maps_num) {
		if (MAP_FAILED == mmap((void *)NULL, (size_t) 1, PROT_READ,
					MAP_SHARED | MAP_ANONYMOUS, (int) -1,
					(off_t) NULL)) {
						perror("mmap");
						exit(4);
		}
	}
	abort();
	{
		char buffer[128];
		sprintf(buffer, "wc -l /proc/%u/maps", getpid());
		system(buffer);
	}
	return 0;
}
== /* mkmmaps.c */

Thanks.



More information about the Binutils mailing list