mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-04-18 18:50:23 +08:00
Handle more ELF section types
note, preinit_array, init_array, and fini_array are ELF section types that can matter to the assembly programmer. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
parent
b2004511dd
commit
dc5939b496
@ -15,6 +15,9 @@ after a real error.
|
||||
\b Add support for the \c{merge} and \c{strings} attributes on ELF
|
||||
sections. See \k{elfsect}.
|
||||
|
||||
\b Add support for the \c{note}, \c{preinit_array}, \c{init_array},
|
||||
and \c{fini_array} sections type in ELF. See \k{elfsect}.
|
||||
|
||||
\b Handle more than 32,633 sections in ELF.
|
||||
|
||||
\S{cl-2.14.02} Version 2.14.02
|
||||
|
131
doc/nasmdoc.src
131
doc/nasmdoc.src
@ -122,15 +122,14 @@
|
||||
\IR{- opunary} \c{-} operator, unary
|
||||
\IR{! opunary} \c{!} operator, unary
|
||||
\IR{alignment, in bin sections} alignment, in \c{bin} sections
|
||||
\IR{alignment, in elf sections} alignment, in \c{elf} sections
|
||||
\IR{alignment, in elf sections} alignment, in ELF sections
|
||||
\IR{alignment, in win32 sections} alignment, in \c{win32} sections
|
||||
\IR{alignment, of elf common variables} alignment, of \c{elf} common
|
||||
\IR{alignment, of elf common variables} alignment, of ELF common
|
||||
variables
|
||||
\IR{alignment, in obj sections} alignment, in \c{obj} sections
|
||||
\IR{a.out, bsd version} \c{a.out}, BSD version
|
||||
\IR{a.out, linux version} \c{a.out}, Linux version
|
||||
\IR{autoconf} Autoconf
|
||||
\IR{bin} bin
|
||||
\IR{bin} \c{bin} output format
|
||||
\IR{bitwise and} bitwise AND
|
||||
\IR{bitwise or} bitwise OR
|
||||
\IR{bitwise xor} bitwise XOR
|
||||
@ -150,8 +149,8 @@ variables
|
||||
\IR{codeview} CodeView debugging format
|
||||
\IR{common object file format} Common Object File Format
|
||||
\IR{common variables, alignment in elf} common variables, alignment
|
||||
in \c{elf}
|
||||
\IR{common, elf extensions to} \c{COMMON}, \c{elf} extensions to
|
||||
in ELF
|
||||
\IR{common, elf extensions to} \c{COMMON}, ELF extensions to
|
||||
\IR{common, obj extensions to} \c{COMMON}, \c{obj} extensions to
|
||||
\IR{declaring structure} declaring structures
|
||||
\IR{default-wrt mechanism} default-\c{WRT} mechanism
|
||||
@ -165,7 +164,8 @@ in \c{elf}
|
||||
\IA{effective address}{effective addresses}
|
||||
\IA{effective-address}{effective addresses}
|
||||
\IR{elf} ELF
|
||||
\IR{elf, 16-bit code and} ELF, 16-bit code and
|
||||
\IR{elf, 16-bit code} ELF, 16-bit code
|
||||
\IR{elf, debug formats} ELF, debug formats
|
||||
\IR{elf shared libraries} ELF, shared libraries
|
||||
\IR{elf32} \c{elf32}
|
||||
\IR{elf64} \c{elf64}
|
||||
@ -181,7 +181,7 @@ in \c{elf}
|
||||
\IR{functions, pascal calling convention} functions, Pascal calling
|
||||
convention
|
||||
\IR{global, aoutb extensions to} \c{GLOBAL}, \c{aoutb} extensions to
|
||||
\IR{global, elf extensions to} \c{GLOBAL}, \c{elf} extensions to
|
||||
\IR{global, elf extensions to} \c{GLOBAL}, ELF extensions to
|
||||
\IR{global, rdf extensions to} \c{GLOBAL}, \c{rdf} extensions to
|
||||
\IR{got} GOT
|
||||
\IR{got relocations} \c{GOT} relocations
|
||||
@ -238,16 +238,16 @@ convention
|
||||
Object File Format
|
||||
\IR{relocations, pic-specific} relocations, PIC-specific
|
||||
\IA{repeating}{repeating code}
|
||||
\IR{section alignment, in elf} section alignment, in \c{elf}
|
||||
\IR{section alignment, in elf} section alignment, in ELF
|
||||
\IR{section alignment, in bin} section alignment, in \c{bin}
|
||||
\IR{section alignment, in obj} section alignment, in \c{obj}
|
||||
\IR{section alignment, in win32} section alignment, in \c{win32}
|
||||
\IR{section, elf extensions to} \c{SECTION}, \c{elf} extensions to
|
||||
\IR{section, elf extensions to} \c{SECTION}, ELF extensions to
|
||||
\IR{section, macho extensions to} \c{SECTION}, \c{macho} extensions to
|
||||
\IR{section, win32 extensions to} \c{SECTION}, \c{win32} extensions to
|
||||
\IR{segment alignment, in bin} segment alignment, in \c{bin}
|
||||
\IR{segment alignment, in obj} segment alignment, in \c{obj}
|
||||
\IR{segment, obj extensions to} \c{SEGMENT}, \c{elf} extensions to
|
||||
\IR{segment, obj extensions to} \c{SEGMENT}, ELF extensions to
|
||||
\IR{segment names, borland pascal} segment names, Borland Pascal
|
||||
\IR{shift command} \c{shift} command
|
||||
\IA{sib}{sib byte}
|
||||
@ -256,11 +256,10 @@ Object File Format
|
||||
\IA{sectalign}{sectalign}
|
||||
\IR{solaris x86} Solaris x86
|
||||
\IA{standard section names}{standardized section names}
|
||||
\IR{strings, elf attribute} \c{strings}
|
||||
\IR{symbols, exporting from dlls} symbols, exporting from DLLs
|
||||
\IR{symbols, importing from dlls} symbols, importing from DLLs
|
||||
\IR{test subdirectory} \c{test} subdirectory
|
||||
\IR{thread local storage in elf} thread local storage, in \c{elf}
|
||||
\IR{thread local storage in elf} thread local storage, in ELF
|
||||
\IR{thread local storage in mach-o} thread local storage, in \c{macho}
|
||||
\IR{tlink} \c{TLINK}
|
||||
\IR{underscore, in c symbols} underscore, in C symbols
|
||||
@ -298,16 +297,16 @@ Object File Format
|
||||
|
||||
The Netwide Assembler, NASM, is an 80x86 and x86-64 assembler designed
|
||||
for portability and modularity. It supports a range of object file
|
||||
formats, including Linux and \c{*BSD} \c{a.out}, \c{ELF}, \c{COFF},
|
||||
\c{Mach-O}, 16-bit and 32-bit \c{OBJ} (OMF) format, \c{Win32} and
|
||||
\c{Win64}. It will also output plain binary files, Intel hex and
|
||||
formats, including Linux and *BSD \c{a.out}, ELF, Mach-O, 16-bit and
|
||||
32-bit \c{.obj} (OMF) format, COFF (including its Win32 and Win64
|
||||
variants.) It can also output plain binary files, Intel hex and
|
||||
Motorola S-Record formats. Its syntax is designed to be simple and
|
||||
easy to understand, similar to the syntax in the Intel Software
|
||||
Developer Manual with minimal complexity. It supports all currently
|
||||
known x86 architectural extensions, and has strong support for macros.
|
||||
|
||||
NASM also comes with a set of utilities for handling the \c{RDOFF}
|
||||
custom object-file format.
|
||||
NASM also comes with a set of utilities for handling its own RDOFF2
|
||||
object-file format.
|
||||
|
||||
\S{legal} \i{License} Conditions
|
||||
|
||||
@ -355,7 +354,7 @@ For example,
|
||||
|
||||
\c nasm -f elf myfile.asm
|
||||
|
||||
will assemble \c{myfile.asm} into an \c{ELF} object file \c{myfile.o}. And
|
||||
will assemble \c{myfile.asm} into an ELF object file \c{myfile.o}. And
|
||||
|
||||
\c nasm -f bin myfile.asm -o myfile.com
|
||||
|
||||
@ -377,7 +376,7 @@ The option \c{-hf} will also list the available output file formats,
|
||||
and what they are.
|
||||
|
||||
If you use Linux but aren't sure whether your system is \c{a.out}
|
||||
or \c{ELF}, type
|
||||
or ELF, type
|
||||
|
||||
\c file nasm
|
||||
|
||||
@ -4376,7 +4375,7 @@ operating in 16-bit mode, 32-bit mode or 64-bit mode. The syntax is
|
||||
\c{BITS XX}, where XX is 16, 32 or 64.
|
||||
|
||||
In most cases, you should not need to use \c{BITS} explicitly. The
|
||||
\c{aout}, \c{coff}, \c{elf}, \c{macho}, \c{win32} and \c{win64}
|
||||
\c{aout}, \c{coff}, \c{elf*}, \c{macho}, \c{win32} and \c{win64}
|
||||
object formats, which are designed for use in 32-bit or 64-bit
|
||||
operating systems, all cause NASM to select 32-bit or 64-bit mode,
|
||||
respectively, by default. The \c{obj} object format allows you
|
||||
@ -4653,9 +4652,8 @@ refer to symbols which \e{are} defined in the same module as the
|
||||
\c ; some code
|
||||
|
||||
\c{GLOBAL}, like \c{EXTERN}, allows object formats to define private
|
||||
extensions by means of a colon. The \c{elf} object format, for
|
||||
example, lets you specify whether global data items are functions or
|
||||
data:
|
||||
extensions by means of a colon. The ELF object format, for example,
|
||||
lets you specify whether global data items are functions or data:
|
||||
|
||||
\c global hashlookup:function, hashtable:data
|
||||
|
||||
@ -4686,8 +4684,8 @@ at the same piece of memory.
|
||||
|
||||
Like \c{GLOBAL} and \c{EXTERN}, \c{COMMON} supports object-format
|
||||
specific extensions. For example, the \c{obj} format allows common
|
||||
variables to be NEAR or FAR, and the \c{elf} format allows you to
|
||||
specify the alignment requirements of a common variable:
|
||||
variables to be NEAR or FAR, and the ELF format allows you to specify
|
||||
the alignment requirements of a common variable:
|
||||
|
||||
\c common commvar 4:near ; works in OBJ
|
||||
\c common intarray 100:4 ; works in ELF: 4 byte aligned
|
||||
@ -4759,7 +4757,7 @@ For example, when mangling local symbols via the generic namespace:
|
||||
This is useful when the directive is needed to be output format
|
||||
agnostic.
|
||||
|
||||
The example is also euquivalent to this, when the output format is \c{elf}:
|
||||
The example is also euquivalent to this, when the output format is ELF:
|
||||
|
||||
\c %pragma elf gprefix _
|
||||
|
||||
@ -5907,8 +5905,8 @@ Format} Object Files
|
||||
The \c{elf32}, \c{elf64} and \c{elfx32} output formats generate
|
||||
\c{ELF32 and ELF64} (Executable and Linkable Format) object files, as
|
||||
used by Linux as well as \i{Unix System V}, including \i{Solaris x86},
|
||||
\i{UnixWare} and \i{SCO Unix}. \c{elf} provides a default output
|
||||
file-name extension of \c{.o}. \c{elf} is a synonym for \c{elf32}.
|
||||
\i{UnixWare} and \i{SCO Unix}. ELF provides a default output
|
||||
file-name extension of \c{.o}. \c{elf} is a synonym for \c{elf32}.
|
||||
|
||||
The \c{elfx32} format is used for the \i{x32} ABI, which is a 32-bit
|
||||
ABI with the CPU in 64-bit mode.
|
||||
@ -5921,8 +5919,8 @@ target operating system (OSABI). This field can be set by using the
|
||||
system. If this directive is not used, the default value will be "UNIX
|
||||
System V ABI" (0) which will work on most systems which support ELF.
|
||||
|
||||
\S{elfsect} \c{elf} extensions to the \c{SECTION} Directive
|
||||
\I{SECTION, elf extensions to}
|
||||
\S{elfsect} ELF extensions to the \c{SECTION} Directive
|
||||
\I{SECTION, ELF extensions to}
|
||||
|
||||
Like the \c{obj} format, \c{elf} allows you to specify additional
|
||||
information on the \c{SECTION} directive line, to control the type
|
||||
@ -5947,23 +5945,42 @@ not.
|
||||
|
||||
\b \i\c{progbits} defines the section to be one with explicit contents
|
||||
stored in the object file: an ordinary code or data section, for
|
||||
example, \i\c{nobits} defines the section to be one with no explicit
|
||||
example.
|
||||
|
||||
\b \i\c{nobits} defines the section to be one with no explicit
|
||||
contents given, such as a BSS section.
|
||||
|
||||
\b \c{align=}, used with a trailing number as in \c{obj}, gives the
|
||||
\b \i\c{note} indicates that this section contains ELF notes. The
|
||||
content of ELF notes are specified using normal assembly instructions;
|
||||
it is up to the programmer to ensure these are valid ELF notes.
|
||||
|
||||
\b \i\c{preinit_array} indicates that this section contains function
|
||||
addresses to be called before any other initialization has happened.
|
||||
|
||||
\b \i\c{init_array} indicates that this section contains function
|
||||
addresses to be called during initialization.
|
||||
|
||||
\b \i\c{fini_array} indicates that this section contains function
|
||||
pointers to be called during termination.
|
||||
|
||||
\b \I{align, ELF attribute}\c{align=}, used with a trailing number as in \c{obj}, gives the
|
||||
\I{section alignment, in elf}\I{alignment, in elf sections}alignment
|
||||
requirements of the section.
|
||||
|
||||
\b \c{ent=} or \c{entsize=} specifies the fundamental data item size
|
||||
for a section which contains either fixed-sized data structures or
|
||||
strings; this is generally used with the \c{merge} attribute (see
|
||||
below.)
|
||||
|
||||
\b \c{byte}, \c{word}, \c{dword}, \c{qword}, \c{tword}, \c{oword},
|
||||
\c{yword}, or \c{zword} are both shorthand for \c{entsize=}, but also
|
||||
sets the default alignment.
|
||||
\c{yword}, or \c{zword} with an optional \c{*}\i{multiplier} specify
|
||||
the fundamental data item size for a section which contains either
|
||||
fixed-sized data structures or strings; it also sets a default
|
||||
alignment. This is generally used with the \c{strings} and \c{merge}
|
||||
attributes (see below.) For example \c{byte*4} defines a unit size of
|
||||
4 bytes, with a default alignment of 1; \c{dword} also defines a unit
|
||||
size of 4 bytes, but with a default alignment of 4. The \c{align=}
|
||||
attribute, if specified, overrides this default alignment.
|
||||
|
||||
\b \i{strings, ELF attribute}\c{strings} indicate that this section
|
||||
\b \I{pointer, ELF attribute}\c{pointer} is equivalent to \c{dword}
|
||||
for \c{elf32} or \c{elfx32}, and \c{qword} for \c{elf64}.
|
||||
|
||||
\b \I{strings, ELF attribute}\c{strings} indicate that this section
|
||||
contains exclusively null-terminated strings. By default these are
|
||||
assumed to be byte strings, but a size specifier can be used to
|
||||
override that.
|
||||
@ -5983,24 +6000,28 @@ qualifiers are:
|
||||
\I\c{.text} \I\c{.rodata} \I\c{.lrodata} \I\c{.data} \I\c{.ldata}
|
||||
\I\c{.bss} \I\c{.lbss} \I\c{.tdata} \I\c{.tbss} \I\c\{.comment}
|
||||
|
||||
\c section .text progbits alloc exec nowrite align=16
|
||||
\c section .rodata progbits alloc noexec nowrite align=4
|
||||
\c section .lrodata progbits alloc noexec nowrite align=4
|
||||
\c section .data progbits alloc noexec write align=4
|
||||
\c section .ldata progbits alloc noexec write align=4
|
||||
\c section .bss nobits alloc noexec write align=4
|
||||
\c section .lbss nobits alloc noexec write align=4
|
||||
\c section .tdata progbits alloc noexec write align=4 tls
|
||||
\c section .tbss nobits alloc noexec write align=4 tls
|
||||
\c section .comment progbits noalloc noexec nowrite align=1
|
||||
\c section other progbits alloc noexec nowrite align=1
|
||||
\c section .text progbits alloc exec nowrite align=16
|
||||
\c section .rodata progbits alloc noexec nowrite align=4
|
||||
\c section .lrodata progbits alloc noexec nowrite align=4
|
||||
\c section .data progbits alloc noexec write align=4
|
||||
\c section .ldata progbits alloc noexec write align=4
|
||||
\c section .bss nobits alloc noexec write align=4
|
||||
\c section .lbss nobits alloc noexec write align=4
|
||||
\c section .tdata progbits alloc noexec write align=4 tls
|
||||
\c section .tbss nobits alloc noexec write align=4 tls
|
||||
\c section .comment progbits noalloc noexec nowrite align=1
|
||||
\c section .preinit_array preinit_array alloc noexec nowrite pointer
|
||||
\c section .init_array init_array alloc noexec nowrite pointer
|
||||
\c section .fini_array fini_array alloc noexec nowrite pointer
|
||||
\c section .note note noalloc noexec nowrite align=1
|
||||
\c section other progbits alloc noexec nowrite align=1
|
||||
|
||||
(Any section name other than those in the above table
|
||||
is treated by default like \c{other} in the above table.
|
||||
Please note that section names are case sensitive.)
|
||||
|
||||
|
||||
\S{elfwrt} \i{Position-Independent Code}\I{PIC}: \c{macho} Special
|
||||
\S{elfwrt} \i{Position-Independent Code}\I{PIC}: ELF Special
|
||||
Symbols and \i\c{WRT}
|
||||
|
||||
Since \c{ELF} does not support segment-base references, the \c{WRT}
|
||||
@ -6138,7 +6159,7 @@ requires that it be aligned on a 4-byte boundary.
|
||||
|
||||
|
||||
\S{elf16} 16-bit code and ELF
|
||||
\I{ELF, 16-bit code and}
|
||||
\I{ELF, 16-bit code}
|
||||
|
||||
The \c{ELF32} specification doesn't provide relocations for 8- and
|
||||
16-bit values, but the GNU \c{ld} linker adds these as an extension.
|
||||
@ -6148,7 +6169,7 @@ be linked as ELF using GNU \c{ld}. If NASM is used with the
|
||||
these relocations is generated.
|
||||
|
||||
\S{elfdbg} Debug formats and ELF
|
||||
\I{ELF, Debug formats and}
|
||||
\I{ELF, debug formats}
|
||||
|
||||
ELF provides debug information in \c{STABS} and \c{DWARF} formats.
|
||||
Line number information is generated for all executable sections, but please
|
||||
|
177
output/outelf.c
177
output/outelf.c
@ -228,23 +228,61 @@ static int32_t elf_sym_sect, elf_gottpoff_sect, elf_tlsie_sect;
|
||||
uint8_t elf_osabi = 0; /* Default OSABI = 0 (System V or Linux) */
|
||||
uint8_t elf_abiver = 0; /* Current ABI version */
|
||||
|
||||
const struct elf_known_section elf_known_sections[] = {
|
||||
{ ".text", SHT_PROGBITS, SHF_ALLOC|SHF_EXECINSTR, 16 },
|
||||
{ ".rodata", SHT_PROGBITS, SHF_ALLOC, 4 },
|
||||
{ ".lrodata", SHT_PROGBITS, SHF_ALLOC, 4 },
|
||||
{ ".data", SHT_PROGBITS, SHF_ALLOC|SHF_WRITE, 4 },
|
||||
{ ".ldata", SHT_PROGBITS, SHF_ALLOC|SHF_WRITE, 4 },
|
||||
{ ".bss", SHT_NOBITS, SHF_ALLOC|SHF_WRITE, 4 },
|
||||
{ ".lbss", SHT_NOBITS, SHF_ALLOC|SHF_WRITE, 4 },
|
||||
{ ".tdata", SHT_PROGBITS, SHF_ALLOC|SHF_WRITE|SHF_TLS, 4 },
|
||||
{ ".tbss", SHT_NOBITS, SHF_ALLOC|SHF_WRITE|SHF_TLS, 4 },
|
||||
{ ".comment", SHT_PROGBITS, 0, 1 },
|
||||
{ NULL, SHT_PROGBITS, SHF_ALLOC, 1 } /* default */
|
||||
/* Known sections with nonstandard defaults. -n means n*pointer size. */
|
||||
struct elf_known_section {
|
||||
const char *name; /* Name of section */
|
||||
int type; /* Section type (SHT_) */
|
||||
uint32_t flags; /* Section flags (SHF_) */
|
||||
int align; /* Section alignment */
|
||||
int entsize; /* Entry size, if applicable */
|
||||
};
|
||||
|
||||
static const struct elf_known_section elf_known_sections[] = {
|
||||
{ ".text", SHT_PROGBITS, SHF_ALLOC|SHF_EXECINSTR, 16, 0 },
|
||||
{ ".rodata", SHT_PROGBITS, SHF_ALLOC, 4, 0 },
|
||||
{ ".lrodata", SHT_PROGBITS, SHF_ALLOC, 4, 0 },
|
||||
{ ".data", SHT_PROGBITS, SHF_ALLOC|SHF_WRITE, 4, 0 },
|
||||
{ ".ldata", SHT_PROGBITS, SHF_ALLOC|SHF_WRITE, 4, 0 },
|
||||
{ ".bss", SHT_NOBITS, SHF_ALLOC|SHF_WRITE, 4, 0 },
|
||||
{ ".lbss", SHT_NOBITS, SHF_ALLOC|SHF_WRITE, 4, 0 },
|
||||
{ ".tdata", SHT_PROGBITS, SHF_ALLOC|SHF_WRITE|SHF_TLS, 4, 0 },
|
||||
{ ".tbss", SHT_NOBITS, SHF_ALLOC|SHF_WRITE|SHF_TLS, 4, 0 },
|
||||
{ ".comment", SHT_PROGBITS, 0, 1, 0 },
|
||||
{ ".preinit_array", SHT_PREINIT_ARRAY, SHF_ALLOC, -1, -1 },
|
||||
{ ".init_array", SHT_INIT_ARRAY, SHF_ALLOC, -1, -1 },
|
||||
{ ".fini_array", SHT_FINI_ARRAY, SHF_ALLOC, -1, -1 },
|
||||
{ ".note", SHT_NOTE, 0, 1, 0 },
|
||||
{ NULL /*default*/, SHT_PROGBITS, SHF_ALLOC, 1, 0 }
|
||||
};
|
||||
|
||||
struct size_unit {
|
||||
char name[8];
|
||||
int bytes;
|
||||
int align;
|
||||
};
|
||||
static const struct size_unit size_units[] =
|
||||
{
|
||||
{ "byte", 1, 1 },
|
||||
{ "word", 2, 2 },
|
||||
{ "dword", 4, 4 },
|
||||
{ "qword", 8, 8 },
|
||||
{ "tword", 10, 2 },
|
||||
{ "tbyte", 10, 2 },
|
||||
{ "oword", 16, 16 },
|
||||
{ "xword", 16, 16 },
|
||||
{ "yword", 32, 32 },
|
||||
{ "zword", 64, 64 },
|
||||
{ "pointer", -1, -1 },
|
||||
{ "", 0, 0 }
|
||||
};
|
||||
|
||||
static inline size_t to_bytes(int val)
|
||||
{
|
||||
return (val >= 0) ? (size_t)val : -val * efmt->word;
|
||||
}
|
||||
|
||||
/* parse section attributes */
|
||||
static void elf_section_attrib(char *name, char *attr, int pass,
|
||||
uint32_t *flags_and, uint32_t *flags_or,
|
||||
static void elf_section_attrib(char *name, char *attr, uint32_t *flags_and, uint32_t *flags_or,
|
||||
uint64_t *alignp, uint64_t *entsize, int *type)
|
||||
{
|
||||
char *opt, *val, *next;
|
||||
@ -286,7 +324,8 @@ static void elf_section_attrib(char *name, char *attr, int pass,
|
||||
} else if (!nasm_stricmp(opt, "write")) {
|
||||
*flags_and |= SHF_WRITE;
|
||||
*flags_or |= SHF_WRITE;
|
||||
} else if (!nasm_stricmp(opt, "nowrite")) {
|
||||
} else if (!nasm_stricmp(opt, "nowrite") ||
|
||||
!nasm_stricmp(opt, "readonly")) {
|
||||
*flags_and |= SHF_WRITE;
|
||||
*flags_or &= ~SHF_WRITE;
|
||||
} else if (!nasm_stricmp(opt, "tls")) {
|
||||
@ -311,52 +350,64 @@ static void elf_section_attrib(char *name, char *attr, int pass,
|
||||
*type = SHT_PROGBITS;
|
||||
} else if (!nasm_stricmp(opt, "nobits")) {
|
||||
*type = SHT_NOBITS;
|
||||
} else if (!nasm_stricmp(opt, "ent") || !nasm_stricmp(opt,"entsize")) {
|
||||
bool err;
|
||||
uint64_t es;
|
||||
if (!val) {
|
||||
nasm_error(ERR_NONFATAL,
|
||||
"section attribute %s without value specified", opt);
|
||||
} else {
|
||||
es = readnum(val, &err);
|
||||
if (err) {
|
||||
nasm_error(ERR_NONFATAL,
|
||||
"invalid value %s for section attribute %s",
|
||||
val, opt);
|
||||
} else {
|
||||
*entsize = es;
|
||||
}
|
||||
}
|
||||
} else if (!nasm_stricmp(opt, "byte")) {
|
||||
xalign = *entsize = 1;
|
||||
} else if (!nasm_stricmp(opt, "word")) {
|
||||
xalign = *entsize = 2;
|
||||
} else if (!nasm_stricmp(opt, "dword")) {
|
||||
xalign = *entsize = 4;
|
||||
} else if (!nasm_stricmp(opt, "qword")) {
|
||||
xalign = *entsize = 8;
|
||||
} else if (!nasm_stricmp(opt, "tword")) {
|
||||
*entsize = 10;
|
||||
xalign = 2;
|
||||
} else if (!nasm_stricmp(opt, "oword")) {
|
||||
xalign = *entsize = 16;
|
||||
} else if (!nasm_stricmp(opt, "yword")) {
|
||||
xalign = *entsize = 32;
|
||||
} else if (!nasm_stricmp(opt, "zword")) {
|
||||
xalign = *entsize = 64;
|
||||
} else if (pass == 1) {
|
||||
nasm_error(ERR_WARNING,
|
||||
"Unknown section attribute '%s' ignored on"
|
||||
" declaration of section `%s'", opt, name);
|
||||
} else if (!nasm_stricmp(opt, "note")) {
|
||||
*type = SHT_NOTE;
|
||||
} else if (!nasm_stricmp(opt, "preinit_array")) {
|
||||
*type = SHT_PREINIT_ARRAY;
|
||||
} else if (!nasm_stricmp(opt, "init_array")) {
|
||||
*type = SHT_INIT_ARRAY;
|
||||
} else if (!nasm_stricmp(opt, "fini_array")) {
|
||||
*type = SHT_FINI_ARRAY;
|
||||
} else {
|
||||
uint64_t mult;
|
||||
size_t l;
|
||||
const char *a = strchr(opt, '*');
|
||||
bool err;
|
||||
const struct size_unit *su;
|
||||
|
||||
if (a) {
|
||||
l = a - opt - 1;
|
||||
mult = readnum(a+1, &err);
|
||||
} else {
|
||||
l = strlen(opt);
|
||||
mult = 1;
|
||||
}
|
||||
|
||||
for (su = size_units; su->bytes; su++) {
|
||||
if (!nasm_strnicmp(opt, su->name, l))
|
||||
break;
|
||||
}
|
||||
|
||||
if (su->bytes) {
|
||||
*entsize = to_bytes(su->bytes) * mult;
|
||||
xalign = to_bytes(su->align);
|
||||
} else {
|
||||
/* Unknown attribute */
|
||||
nasm_error(ERR_WARNING|ERR_PASS1,
|
||||
"unknown section attribute '%s' ignored on"
|
||||
" declaration of section `%s'", opt, name);
|
||||
}
|
||||
}
|
||||
opt = next;
|
||||
}
|
||||
|
||||
if (!align)
|
||||
align = xalign;
|
||||
switch (*type) {
|
||||
case SHT_PREINIT_ARRAY:
|
||||
case SHT_INIT_ARRAY:
|
||||
case SHT_FINI_ARRAY:
|
||||
if (!xalign)
|
||||
xalign = efmt->word;
|
||||
if (!*entsize)
|
||||
*entsize = efmt->word;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!align)
|
||||
align = SHA_ANY;
|
||||
align = xalign;
|
||||
if (!align)
|
||||
align = SHA_ANY;
|
||||
|
||||
*alignp = align;
|
||||
}
|
||||
@ -618,6 +669,8 @@ static int32_t elf_section_names(char *name, int pass, int *bits)
|
||||
struct hash_insert hi;
|
||||
int type;
|
||||
|
||||
(void)pass;
|
||||
|
||||
if (!name) {
|
||||
*bits = ofmt->maxbits;
|
||||
return def_seg;
|
||||
@ -628,8 +681,7 @@ static int32_t elf_section_names(char *name, int pass, int *bits)
|
||||
*p++ = '\0';
|
||||
flags_and = flags_or = type = align = entsize = 0;
|
||||
|
||||
elf_section_attrib(name, p, pass, &flags_and,
|
||||
&flags_or, &align, &entsize, &type);
|
||||
elf_section_attrib(name, p, &flags_and, &flags_or, &align, &entsize, &type);
|
||||
|
||||
hp = hash_find(§ion_by_name, name, &hi);
|
||||
if (hp) {
|
||||
@ -649,7 +701,10 @@ static int32_t elf_section_names(char *name, int pass, int *bits)
|
||||
}
|
||||
|
||||
type = type ? type : ks->type;
|
||||
align = align ? align : ks->align;
|
||||
if (!align)
|
||||
align = to_bytes(ks->align);
|
||||
if (!entsize)
|
||||
entsize = to_bytes(ks->entsize);
|
||||
flags = (ks->flags & ~flags_and) | flags_or;
|
||||
|
||||
s = elf_make_section(name, type, flags, align);
|
||||
@ -1035,7 +1090,7 @@ static void elf32_out(int32_t segto, const void *data,
|
||||
|
||||
switch (type) {
|
||||
case OUT_RESERVE:
|
||||
if (s->type == SHT_PROGBITS) {
|
||||
if (s->type != SHT_NOBITS) {
|
||||
nasm_error(ERR_WARNING, "uninitialized space declared in"
|
||||
" non-BSS section `%s': zeroing", s->name);
|
||||
elf_sect_write(s, NULL, size);
|
||||
@ -1246,7 +1301,7 @@ static void elf64_out(int32_t segto, const void *data,
|
||||
|
||||
switch (type) {
|
||||
case OUT_RESERVE:
|
||||
if (s->type == SHT_PROGBITS) {
|
||||
if (s->type != SHT_NOBITS) {
|
||||
nasm_error(ERR_WARNING, "uninitialized space declared in"
|
||||
" non-BSS section `%s': zeroing", s->name);
|
||||
elf_sect_write(s, NULL, size);
|
||||
@ -1528,7 +1583,7 @@ static void elfx32_out(int32_t segto, const void *data,
|
||||
|
||||
switch (type) {
|
||||
case OUT_RESERVE:
|
||||
if (s->type == SHT_PROGBITS) {
|
||||
if (s->type != SHT_NOBITS) {
|
||||
nasm_error(ERR_WARNING, "uninitialized space declared in"
|
||||
" non-BSS section `%s': zeroing", s->name);
|
||||
elf_sect_write(s, NULL, size);
|
||||
|
@ -53,15 +53,6 @@
|
||||
/* this stuff is needed for the dwarf/stabs debugging format */
|
||||
#define TY_DEBUGSYMLIN 0x40 /* internal call to debug_out */
|
||||
|
||||
/* Known sections with nonstandard defaults */
|
||||
struct elf_known_section {
|
||||
const char *name; /* Name of section */
|
||||
int type; /* Section type (SHT_) */
|
||||
uint32_t flags; /* Section flags (SHF_) */
|
||||
uint32_t align; /* Section alignment */
|
||||
};
|
||||
extern const struct elf_known_section elf_known_sections[];
|
||||
|
||||
/*
|
||||
* Debugging ELF sections (section indicies starting with sec_debug)
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user