ELF: handle more than 32,633 sections

Dead code elimination in ELF uses separate ELF sections for every
functions or data items that may be garbage collected. This can end up
being more than 32,633 sections which, when the ELF internal and
relocation sections are added in, can exceed the legacy ELF maximum of
65,279 sections.

Newer versions of the ELF specification has added support for much
larger number of sections by putting a place holder value (usually
SHN_XINDEX == 0xffff, but 0 in some cases) into fields where the
section index is a 16-bit value, and storing the full value in a
diffent place: the program header uses entries in section header 0,
the symbol table uses an auxiliary segment with the additional
indicies; the section header did not need it as the sh_link field is
already 32 (or 64) bits long.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin 2019-02-26 00:02:35 -08:00
parent 437e0ffa01
commit b2004511dd
8 changed files with 583 additions and 566 deletions

View File

@ -15,6 +15,8 @@ after a real error.
\b Add support for the \c{merge} and \c{strings} attributes on ELF
sections. See \k{elfsect}.
\b Handle more than 32,633 sections in ELF.
\S{cl-2.14.02} Version 2.14.02
\b Fix crash due to multiple errors or warnings during the code

View File

@ -160,7 +160,11 @@
#define SHT_REL 9
#define SHT_SHLIB 10
#define SHT_DYNSYM 11
#define SHT_NUM 12
#define SHT_INIT_ARRAY 14
#define SHT_FINI_ARRAY 15
#define SHT_PREINIT_ARRAY 16
#define SHT_GROUP 17
#define SHT_SYMTAB_SHNDX 18
#define SHT_LOPROC 0x70000000
#define SHT_HIPROC 0x7fffffff
#define SHT_LOUSER 0x80000000
@ -179,14 +183,25 @@
#define SHF_TLS (1 << 10) /* Section hold thread-local data. */
/* Special section numbers */
#define SHN_UNDEF 0
#define SHN_UNDEF 0x0000
#define SHN_LORESERVE 0xff00
#define SHN_LOPROC 0xff00
#define SHN_HIPROC 0xff1f
#define SHN_ABS 0xfff1
#define SHN_COMMON 0xfff2
#define SHN_XINDEX 0xffff
#define SHN_HIRESERVE 0xffff
/* Same, but signed/sign-extended */
#define XSHN_UNDEF ((int16_t)SHN_UNDEF)
#define XSHN_LORESERVE ((int16_t)SHN_LORESERVE)
#define XSHN_LOPROC ((int16_t)SHN_LOPROC)
#define XSHN_HIPROC ((int16_t)SHN_HIPROC)
#define XSHN_ABS ((int16_t)SHN_ABS)
#define XSHN_COMMON ((int16_t)SHN_COMMON)
#define XSHN_XINDEX ((int16_t)SHN_XINDEX)
#define XSHN_HIRESERVE ((int16_t)SHN_HIRESERVE)
/* Section align flag */
#define SHA_ANY 1 /* No alignment constraint */

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2009 The NASM Authors - All Rights Reserved
* Copyright 1996-2019 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
@ -63,21 +63,13 @@ struct elf_known_section {
extern const struct elf_known_section elf_known_sections[];
/*
* Special ELF sections (after the real sections but before debugging ones)
*/
#define sec_shstrtab (nsects + 1)
#define sec_symtab (nsects + 2)
#define sec_strtab (nsects + 3)
#define sec_numspecial 3
/*
* Debugging ELF sections (last in the file)
* Debugging ELF sections (section indicies starting with sec_debug)
*/
/* stabs */
#define sec_stab (nsections-3)
#define sec_stabstr (nsections-2)
#define sec_rel_stab (nsections-1)
#define sec_stab (sec_debug + 0)
#define sec_stabstr (sec_debug + 1)
#define sec_rel_stab (sec_debug + 2)
/* stabs symbol table format */
struct stabentry {
@ -89,16 +81,16 @@ struct stabentry {
};
/* dwarf */
#define sec_debug_aranges (nsections-10)
#define sec_rela_debug_aranges (nsections-9)
#define sec_debug_pubnames (nsections-8)
#define sec_debug_info (nsections-7)
#define sec_rela_debug_info (nsections-6)
#define sec_debug_abbrev (nsections-5)
#define sec_debug_line (nsections-4)
#define sec_rela_debug_line (nsections-3)
#define sec_debug_frame (nsections-2)
#define sec_debug_loc (nsections-1)
#define sec_debug_aranges (sec_debug + 0)
#define sec_rela_debug_aranges (sec_debug + 1)
#define sec_debug_pubnames (sec_debug + 2)
#define sec_debug_info (sec_debug + 3)
#define sec_rela_debug_info (sec_debug + 4)
#define sec_debug_abbrev (sec_debug + 5)
#define sec_debug_line (sec_debug + 6)
#define sec_rela_debug_line (sec_debug + 7)
#define sec_debug_frame (sec_debug + 8)
#define sec_debug_loc (sec_debug + 9)
extern uint8_t elf_osabi;
extern uint8_t elf_abiver;
@ -137,15 +129,14 @@ struct elf_section {
uint64_t len;
uint64_t size;
uint64_t nrelocs;
int32_t index; /* NASM index */
int32_t index; /* NASM index or NO_SEG if internal */
int shndx; /* ELF index */
int type; /* SHT_PROGBITS or SHT_NOBITS */
int type; /* SHT_* */
uint64_t align; /* alignment: power of two */
uint64_t flags; /* section flags */
uint64_t entsize; /* entry size */
char *name;
struct SAA *rel;
uint64_t rellen;
struct elf_reloc *head;
struct elf_reloc **tail;
struct rbtree *gsyms; /* global symbols in section */

2
test/fewsecs.asm Normal file
View File

@ -0,0 +1,2 @@
%assign NSECS 64
%include "manysecs.asm"

View File

@ -1,6 +1,15 @@
%ifndef NSECS
%assign NSECS 16384
%endif
%assign NSECS ((NSECS+3) & ~3)
%assign n 0
%rep 10000
%rep NSECS
%assign gcom (n & ~3) + 2
section .text %+ n progbits exec
start_ %+ n:
nop
%assign n n+1
jmp start_ %+ gcom
%assign n n+1
%endrep

3
test/moresecs.asm Normal file
View File

@ -0,0 +1,3 @@
; Less than 65,279 data sections, but more total sections
%assign NSECS 37600
%include "manysecs.asm"

3
test/mostsecs.asm Normal file
View File

@ -0,0 +1,3 @@
; More than 65,279 data sections
%assign NSECS 131072
%include "manysecs.asm"