* [PATCH 0/7] ELF: Don't require section header on ELF objects
@ 2020-03-08 23:42 H.J. Lu
2020-03-08 23:42 ` [PATCH 1/7] " H.J. Lu
` (7 more replies)
0 siblings, 8 replies; 18+ messages in thread
From: H.J. Lu @ 2020-03-08 23:42 UTC (permalink / raw)
To: binutils
Section header isn't mandatory on ELF executable nor shared library.
This patch set adds a new linker option, -z nosectionheader, to omit
ELF section header when building an executable or shared library, an
objcopy and strip option, --remove-section-header, to remove ELF
section header from an executable or shared library.
The PT_DYNAMIC segment contains DT_HASH/DT_GNU_HASH/DT_MIPS_XHASH,
DT_STRTAB, DT_SYMTAB, DT_STRSZ and DT_SYMENT entries, which can be
used to reconstruct dynamic symbol table when section header isn't
available. For DT_HASH, the number of dynamic symbol table entries
equals the number of chains. For DT_GNU_HASH/DT_MIPS_XHASH, only
defined symbols with non-STB_LOCAL indings are in hash table. Since
in dynamic symbol table, all symbols with STB_LOCAL binding are placed
before symbols with other bindings and all undefined symbols are placed
before defined ones, the highest symbol index in DT_GNU_HASH and
DT_MIPS_XHASH is the highest dynamic symbol table index.
H.J. Lu (5):
bfd: Reconstruct dynamic symbol table from PT_DYNAMIC segment
readelf: Compute dynamic symbol table size from hash table
binutils: Add --remove-section-header tests
ld: Add tests for -z nosectionheader and --remove-section-header
ld: Add -z nosectionheader test to bootstrap.exp
Kaylee Blake (2):
ELF: Don't require section header on ELF objects
ld: Add a simple test for -z nosectionheader
bfd/bfd-in2.h | 8 +-
bfd/bfd.c | 8 +-
bfd/elf-bfd.h | 8 +
bfd/elf.c | 443 ++++++++++++++++++
bfd/elfcode.h | 174 ++++++-
bfd/elflink.c | 148 ++++--
bfd/elfxx-target.h | 6 +-
binutils/NEWS | 3 +
binutils/doc/binutils.texi | 12 +
binutils/objcopy.c | 54 ++-
binutils/readelf.c | 226 ++++-----
binutils/testsuite/binutils-all/objcopy.exp | 13 +
.../testsuite/binutils-all/remove-header-1.d | 8 +
ld/NEWS | 3 +
ld/emultempl/elf.em | 4 +
ld/ld.h | 3 +
ld/ld.texi | 6 +
ld/ldlang.c | 4 +
ld/lexsup.c | 12 +
ld/testsuite/ld-bootstrap/bootstrap.exp | 10 +-
ld/testsuite/ld-elf/hash.d | 8 +-
ld/testsuite/ld-elf/no-section-header.exp | 336 +++++++++++++
ld/testsuite/ld-elf/nosectionheader.d | 12 +
ld/testsuite/ld-elf/pr13195.d | 2 +-
ld/testsuite/ld-elf/pr22393-2a-no-sec-hdr.nd | 3 +
ld/testsuite/ld-elf/pr22393-2a-no-sec-hdr.rd | 20 +
ld/testsuite/ld-elf/pr22393-2a-sec-hdr.rd | 19 +
ld/testsuite/ld-elf/pr22393-2b-no-sec-hdr.nd | 3 +
ld/testsuite/ld-elf/pr22393-2b-no-sec-hdr.rd | 20 +
.../ld-elf/pr22393-2b-static-no-sec-hdr.rd | 12 +
ld/testsuite/ld-elf/start-noheader.rd | 11 +
.../ld-elf/start-shared-noheader-gnu.rd | 22 +
.../ld-elf/start-shared-noheader-sysv.rd | 22 +
ld/testsuite/ld-elf/start-shared-noheader.nd | 5 +
ld/testsuite/ld-elfvsb/hidden2.d | 2 +-
ld/testsuite/ld-mips-elf/hash2.d | 8 +-
36 files changed, 1458 insertions(+), 200 deletions(-)
create mode 100644 binutils/testsuite/binutils-all/remove-header-1.d
create mode 100644 ld/testsuite/ld-elf/no-section-header.exp
create mode 100644 ld/testsuite/ld-elf/nosectionheader.d
create mode 100644 ld/testsuite/ld-elf/pr22393-2a-no-sec-hdr.nd
create mode 100644 ld/testsuite/ld-elf/pr22393-2a-no-sec-hdr.rd
create mode 100644 ld/testsuite/ld-elf/pr22393-2a-sec-hdr.rd
create mode 100644 ld/testsuite/ld-elf/pr22393-2b-no-sec-hdr.nd
create mode 100644 ld/testsuite/ld-elf/pr22393-2b-no-sec-hdr.rd
create mode 100644 ld/testsuite/ld-elf/pr22393-2b-static-no-sec-hdr.rd
create mode 100644 ld/testsuite/ld-elf/start-noheader.rd
create mode 100644 ld/testsuite/ld-elf/start-shared-noheader-gnu.rd
create mode 100644 ld/testsuite/ld-elf/start-shared-noheader-sysv.rd
create mode 100644 ld/testsuite/ld-elf/start-shared-noheader.nd
--
2.24.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 1/7] ELF: Don't require section header on ELF objects
2020-03-08 23:42 [PATCH 0/7] ELF: Don't require section header on ELF objects H.J. Lu
@ 2020-03-08 23:42 ` H.J. Lu
2020-03-08 23:42 ` [PATCH 2/7] bfd: Reconstruct dynamic symbol table from PT_DYNAMIC segment H.J. Lu
` (6 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: H.J. Lu @ 2020-03-08 23:42 UTC (permalink / raw)
To: binutils; +Cc: Kaylee Blake
From: Kaylee Blake <klkblake@gmail.com>
Section header isn't mandatory on ELF executable nor shared library.
This patch adds a new linker option, -z nosectionheader, to omit ELF
section header when building an executable or shared library, an
objcopy and strip option, --remove-section-header, to remove ELF
section header from an executable or shared library.
The PT_DYNAMIC segment contains DT_HASH/DT_GNU_HASH/DT_MIPS_XHASH,
DT_STRTAB, DT_SYMTAB, DT_STRSZ and DT_SYMENT entries, which can be
used to reconstruct dynamic symbol table when section header isn't
available. For DT_HASH, the number of dynamic symbol table entries
equals the number of chains. For DT_GNU_HASH/DT_MIPS_XHASH, only
defined symbols with non-STB_LOCAL indings are in hash table. Since
in dynamic symbol table, all symbols with STB_LOCAL binding are placed
before symbols with other bindings and all undefined symbols are placed
before defined ones, the highest symbol index in DT_GNU_HASH and
DT_MIPS_XHASH is the highest dynamic symbol table index.
bfd/
2020-03-XX H.J. Lu <hongjiu.lu@intel.com>
Kaylee Blake <klkblake@gmail.com>
PR ld/25617
* bfd.c (BFD_NO_SECTION_HEADER): New.
(BFD_FLAGS_SAVED): Add BFD_NO_SECTION_HEADER.
(BFD_FLAGS_FOR_BFD_USE_MASK): Likewise.
* elfcode.h (elf_swap_ehdr_out): Omit section header on
non-relocatable output with BFD_NO_SECTION_HEADER.
(elf_write_shdrs_and_ehdr): Likewise.
* elfxx-target.h (TARGET_BIG_SYM): Add BFD_NO_SECTION_HEADER
to object_flags.
(TARGET_LITTLE_SYM): Likewise.
* bfd-in2.h: Regenerated.
binutils/
2020-03-XX H.J. Lu <hongjiu.lu@intel.com>
PR ld/25617
* NEWS: Mention --remove-section-header for objcopy and strip.
* doc/binutils.texi: Document --remove-section-header for objcopy
and strip.
* objcopy.c (remove_section_header): New.
(command_line_switch): Add OPTION_REMOVE_SECTION_HEADER.
(strip_options): Add --remove-section-header.
(copy_options): Likewise.
(copy_usage): Add --remove-section-header.
(strip_usage): Likewise.
(copy_object): Renamed to ...
(copy_object_1): This. Issue a warning for
--remove-section-header on non-ELF targets.
(copy_object): New.
(strip_main): Handle OPTION_REMOVE_SECTION_HEADER.
(copy_main): Likewise.
ld/
2020-03-XX H.J. Lu <hongjiu.lu@intel.com>
Kaylee Blake <klkblake@gmail.com>
PR ld/25617
* NEWS: Mention -z nosectionheader.
* emultempl/elf.em: Support -z sectionheader and
-z nosectionheader.
* ld.h (ld_config_type): Add no_section_header.
* ld.texi: Document -z sectionheader and -z nosectionheader.
* ldlang.c (ldlang_open_output): Handle
config.no_section_header.
* lexsup.c (parse_args): Disallow -z nosectionheader with -r.
(elf_static_list_options): Add -z sectionheader and
-z nosectionheader.
---
bfd/bfd-in2.h | 8 ++++--
bfd/bfd.c | 8 ++++--
bfd/elfcode.h | 41 ++++++++++++++++++++++-------
bfd/elfxx-target.h | 6 +++--
binutils/NEWS | 3 +++
binutils/doc/binutils.texi | 12 +++++++++
binutils/objcopy.c | 54 ++++++++++++++++++++++++++++++++++++--
ld/NEWS | 3 +++
ld/emultempl/elf.em | 4 +++
ld/ld.h | 3 +++
ld/ld.texi | 6 +++++
ld/ldlang.c | 4 +++
ld/lexsup.c | 12 +++++++++
13 files changed, 146 insertions(+), 18 deletions(-)
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 37114607b5..d81d0e20dd 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -6588,17 +6588,21 @@ struct bfd
/* Put pathnames into archives (non-POSIX). */
#define BFD_ARCHIVE_FULL_PATH 0x100000
+ /* Don't generate ELF section header. */
+#define BFD_NO_SECTION_HEADER 0x200000
+
/* Flags bits to be saved in bfd_preserve_save. */
#define BFD_FLAGS_SAVED \
(BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \
| BFD_PLUGIN | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON \
- | BFD_USE_ELF_STT_COMMON)
+ | BFD_USE_ELF_STT_COMMON | BFD_NO_SECTION_HEADER)
/* Flags bits which are for BFD use only. */
#define BFD_FLAGS_FOR_BFD_USE_MASK \
(BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \
| BFD_PLUGIN | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT \
- | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON)
+ | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON \
+ | BFD_NO_SECTION_HEADER)
/* The format which belongs to the BFD. (object, core, etc.) */
ENUM_BITFIELD (bfd_format) format : 3;
diff --git a/bfd/bfd.c b/bfd/bfd.c
index 1c1238c036..366e662592 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -176,17 +176,21 @@ CODE_FRAGMENT
. {* Put pathnames into archives (non-POSIX). *}
.#define BFD_ARCHIVE_FULL_PATH 0x100000
.
+. {* Don't generate ELF section header. *}
+.#define BFD_NO_SECTION_HEADER 0x200000
+.
. {* Flags bits to be saved in bfd_preserve_save. *}
.#define BFD_FLAGS_SAVED \
. (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \
. | BFD_PLUGIN | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON \
-. | BFD_USE_ELF_STT_COMMON)
+. | BFD_USE_ELF_STT_COMMON | BFD_NO_SECTION_HEADER)
.
. {* Flags bits which are for BFD use only. *}
.#define BFD_FLAGS_FOR_BFD_USE_MASK \
. (BFD_IN_MEMORY | BFD_COMPRESS | BFD_DECOMPRESS | BFD_LINKER_CREATED \
. | BFD_PLUGIN | BFD_TRADITIONAL_FORMAT | BFD_DETERMINISTIC_OUTPUT \
-. | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON)
+. | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON \
+. | BFD_NO_SECTION_HEADER)
.
. {* The format which belongs to the BFD. (object, core, etc.) *}
. ENUM_BITFIELD (bfd_format) format : 3;
diff --git a/bfd/elfcode.h b/bfd/elfcode.h
index 18a6dac64e..4dde24e02a 100644
--- a/bfd/elfcode.h
+++ b/bfd/elfcode.h
@@ -266,6 +266,10 @@ elf_swap_ehdr_out (bfd *abfd,
{
unsigned int tmp;
int signed_vma = get_elf_backend_data (abfd)->sign_extend_vma;
+ /* Relocatable object must have section header. */
+ bfd_boolean no_section_header
+ = ((abfd->flags & BFD_NO_SECTION_HEADER) != 0
+ && (abfd->flags & (EXEC_P | DYNAMIC)) != 0);
memcpy (dst->e_ident, src->e_ident, EI_NIDENT);
/* note that all elements of dst are *arrays of unsigned char* already... */
H_PUT_16 (abfd, src->e_type, dst->e_type);
@@ -276,7 +280,10 @@ elf_swap_ehdr_out (bfd *abfd,
else
H_PUT_WORD (abfd, src->e_entry, dst->e_entry);
H_PUT_WORD (abfd, src->e_phoff, dst->e_phoff);
- H_PUT_WORD (abfd, src->e_shoff, dst->e_shoff);
+ if (no_section_header)
+ H_PUT_WORD (abfd, 0, dst->e_shoff);
+ else
+ H_PUT_WORD (abfd, src->e_shoff, dst->e_shoff);
H_PUT_32 (abfd, src->e_flags, dst->e_flags);
H_PUT_16 (abfd, src->e_ehsize, dst->e_ehsize);
H_PUT_16 (abfd, src->e_phentsize, dst->e_phentsize);
@@ -284,15 +291,24 @@ elf_swap_ehdr_out (bfd *abfd,
if (tmp > PN_XNUM)
tmp = PN_XNUM;
H_PUT_16 (abfd, tmp, dst->e_phnum);
- H_PUT_16 (abfd, src->e_shentsize, dst->e_shentsize);
- tmp = src->e_shnum;
- if (tmp >= (SHN_LORESERVE & 0xffff))
- tmp = SHN_UNDEF;
- H_PUT_16 (abfd, tmp, dst->e_shnum);
- tmp = src->e_shstrndx;
- if (tmp >= (SHN_LORESERVE & 0xffff))
- tmp = SHN_XINDEX & 0xffff;
- H_PUT_16 (abfd, tmp, dst->e_shstrndx);
+ if (no_section_header)
+ {
+ H_PUT_16 (abfd, 0, dst->e_shentsize);
+ H_PUT_16 (abfd, 0, dst->e_shnum);
+ H_PUT_16 (abfd, 0, dst->e_shstrndx);
+ }
+ else
+ {
+ H_PUT_16 (abfd, src->e_shentsize, dst->e_shentsize);
+ tmp = src->e_shnum;
+ if (tmp >= (SHN_LORESERVE & 0xffff))
+ tmp = SHN_UNDEF;
+ H_PUT_16 (abfd, tmp, dst->e_shnum);
+ tmp = src->e_shstrndx;
+ if (tmp >= (SHN_LORESERVE & 0xffff))
+ tmp = SHN_XINDEX & 0xffff;
+ H_PUT_16 (abfd, tmp, dst->e_shstrndx);
+ }
}
/* Translate an ELF section header table entry in external format into an
@@ -1041,6 +1057,11 @@ elf_write_shdrs_and_ehdr (bfd *abfd)
|| bfd_bwrite (&x_ehdr, amt, abfd) != amt)
return FALSE;
+ /* Relocatable object must have section header. */
+ if ((abfd->flags & BFD_NO_SECTION_HEADER) != 0
+ && (abfd->flags & (EXEC_P | DYNAMIC)) != 0)
+ return TRUE;
+
/* Some fields in the first section header handle overflow of ehdr
fields. */
if (i_ehdrp->e_phnum >= PN_XNUM)
diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
index 1ae17f45ee..8d25c84e80 100644
--- a/bfd/elfxx-target.h
+++ b/bfd/elfxx-target.h
@@ -970,7 +970,8 @@ const bfd_target TARGET_BIG_SYM =
/* object_flags: mask of all file flags */
(HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS
| DYNAMIC | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS
- | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON),
+ | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON
+ | BFD_NO_SECTION_HEADER),
/* section_flags: mask of all section flags */
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY
@@ -1071,7 +1072,8 @@ const bfd_target TARGET_LITTLE_SYM =
/* object_flags: mask of all file flags */
(HAS_RELOC | EXEC_P | HAS_LINENO | HAS_DEBUG | HAS_SYMS | HAS_LOCALS
| DYNAMIC | WP_TEXT | D_PAGED | BFD_COMPRESS | BFD_DECOMPRESS
- | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON),
+ | BFD_COMPRESS_GABI | BFD_CONVERT_ELF_COMMON | BFD_USE_ELF_STT_COMMON
+ | BFD_NO_SECTION_HEADER),
/* section_flags: mask of all section flags */
(SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY
diff --git a/binutils/NEWS b/binutils/NEWS
index 1650a3ac93..5116e2eedc 100644
--- a/binutils/NEWS
+++ b/binutils/NEWS
@@ -1,5 +1,8 @@
-*- text -*-
+* Add command-line option, --remove-section-header, to objcopy and strip
+ to remove ELF section header from an executable or shared library.
+
Changes in 2.34:
* Binutils now supports debuginfod, an HTTP server for distributing
diff --git a/binutils/doc/binutils.texi b/binutils/doc/binutils.texi
index de3f1babb2..ece82e9e39 100644
--- a/binutils/doc/binutils.texi
+++ b/binutils/doc/binutils.texi
@@ -1186,6 +1186,7 @@ objcopy [@option{-F} @var{bfdname}|@option{--target=}@var{bfdname}]
[@option{-R} @var{sectionpattern}|@option{--remove-section=}@var{sectionpattern}]
[@option{--keep-section=}@var{sectionpattern}]
[@option{--remove-relocations=}@var{sectionpattern}]
+ [@option{--remove-section-header}]
[@option{-p}|@option{--preserve-dates}]
[@option{-D}|@option{--enable-deterministic-archives}]
[@option{-U}|@option{--disable-deterministic-archives}]
@@ -1403,6 +1404,11 @@ will remove all relocations for sections matching the pattern
'.text.*', but will not remove relocations for the section
'.text.foo'.
+@item --remove-section-header
+Remove section header from an ELF executable or shared object. This
+option is specific to ELF files and is ignored on relocatable object
+files. Implies @option{--strip-all} and @option{--merge-notes}.
+
@item -S
@itemx --strip-all
Do not copy relocation and symbol information from the source file.
@@ -3262,6 +3268,7 @@ strip [@option{-F} @var{bfdname} |@option{--target=}@var{bfdname}]
[@option{-R} @var{sectionname} |@option{--remove-section=}@var{sectionname}]
[@option{--keep-section=}@var{sectionpattern}]
[@option{--remove-relocations=}@var{sectionpattern}]
+ [@option{--remove-section-header}]
[@option{-o} @var{file}] [@option{-p}|@option{--preserve-dates}]
[@option{-D}|@option{--enable-deterministic-archives}]
[@option{-U}|@option{--disable-deterministic-archives}]
@@ -3363,6 +3370,11 @@ will remove all relocations for sections matching the pattern
'.text.*', but will not remove relocations for the section
'.text.foo'.
+@item --remove-section-header
+Remove section header from an ELF executable or shared object. This
+option is specific to ELF files and is ignored on relocatable object
+files. Implies @option{--strip-all} and @option{--merge-notes}.
+
@item -s
@itemx --strip-all
Remove all symbols.
diff --git a/binutils/objcopy.c b/binutils/objcopy.c
index 09facf0061..10891bc3f0 100644
--- a/binutils/objcopy.c
+++ b/binutils/objcopy.c
@@ -96,6 +96,9 @@ static bfd_boolean preserve_dates; /* Preserve input file timestamp. */
static int deterministic = -1; /* Enable deterministic archives. */
static int status = 0; /* Exit status. */
+/* Remove section header. */
+static bfd_boolean remove_section_header = FALSE;
+
static bfd_boolean merge_notes = FALSE; /* Merge note sections. */
typedef struct merged_note_section
@@ -352,6 +355,7 @@ enum command_line_switch
OPTION_REDEFINE_SYMS,
OPTION_REMOVE_LEADING_CHAR,
OPTION_REMOVE_RELOCS,
+ OPTION_REMOVE_SECTION_HEADER,
OPTION_RENAME_SECTION,
OPTION_REVERSE_BYTES,
OPTION_PE_SECTION_ALIGNMENT,
@@ -399,6 +403,7 @@ static struct option strip_options[] =
{"preserve-dates", no_argument, 0, 'p'},
{"remove-section", required_argument, 0, 'R'},
{"remove-relocations", required_argument, 0, OPTION_REMOVE_RELOCS},
+ {"remove-section-header", no_argument, 0, OPTION_REMOVE_SECTION_HEADER},
{"strip-all", no_argument, 0, 's'},
{"strip-debug", no_argument, 0, 'S'},
{"strip-dwo", no_argument, 0, OPTION_STRIP_DWO},
@@ -487,6 +492,7 @@ static struct option copy_options[] =
{"remove-leading-char", no_argument, 0, OPTION_REMOVE_LEADING_CHAR},
{"remove-section", required_argument, 0, 'R'},
{"remove-relocations", required_argument, 0, OPTION_REMOVE_RELOCS},
+ {"remove-section-header", no_argument, 0, OPTION_REMOVE_SECTION_HEADER},
{"rename-section", required_argument, 0, OPTION_RENAME_SECTION},
{"reverse-bytes", required_argument, 0, OPTION_REVERSE_BYTES},
{"section-alignment", required_argument, 0, OPTION_PE_SECTION_ALIGNMENT},
@@ -582,6 +588,7 @@ copy_usage (FILE *stream, int exit_status)
--add-gnu-debuglink=<file> Add section .gnu_debuglink linking to <file>\n\
-R --remove-section <name> Remove section <name> from the output\n\
--remove-relocations <name> Remove relocations from section <name>\n\
+ --remove-section-header Remove section header from the output\n\
-S --strip-all Remove all symbol and relocation information\n\
-g --strip-debug Remove all debugging symbols & sections\n\
--strip-dwo Remove all DWO sections\n\
@@ -719,6 +726,7 @@ strip_usage (FILE *stream, int exit_status)
fprintf (stream, _("\
-R --remove-section=<name> Also remove section <name> from the output\n\
--remove-relocations <name> Remove relocations from section <name>\n\
+ --remove-section-header Remove section header from the output\n\
-s --strip-all Remove all symbol and relocation information\n\
-g -S -d --strip-debug Remove all debugging symbols & sections\n\
--strip-dwo Remove all DWO sections\n\
@@ -2583,7 +2591,7 @@ check_new_section_flags (flagword flags, bfd * abfd, const char * secname)
Returns TRUE upon success, FALSE otherwise. */
static bfd_boolean
-copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
+copy_object_1 (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
{
bfd_vma start;
long symcount;
@@ -2637,6 +2645,13 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
bfd_get_archive_filename (ibfd));
return FALSE;
}
+
+ if (remove_section_header)
+ {
+ non_fatal (_("--remove_section_header is unsupported on `%s'"),
+ bfd_get_archive_filename (ibfd));
+ return FALSE;
+ }
}
if (verbose)
@@ -3360,7 +3375,7 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
free (merged);
}
}
- else if (merge_notes && ! is_strip)
+ else if (merge_notes && ! is_strip && ! remove_section_header)
non_fatal (_("%s: Could not find any mergeable note sections"),
bfd_get_filename (ibfd));
@@ -3458,6 +3473,34 @@ copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
return TRUE;
}
+/* Copy object file IBFD onto OBFD, preserve strip_symbols and
+ * saved_merge_notes, which may be changed by --remove-section-header.
+ Returns TRUE upon success, FALSE otherwise. */
+
+static bfd_boolean
+copy_object (bfd *ibfd, bfd *obfd, const bfd_arch_info_type *input_arch)
+{
+ enum strip_action saved_strip_symbols = strip_symbols;
+ bfd_boolean saved_merge_notes = merge_notes;
+ bfd_boolean res;
+
+ if (bfd_get_flavour (ibfd) == bfd_target_elf_flavour
+ && remove_section_header
+ && (ibfd->flags & (EXEC_P | DYNAMIC)) != 0)
+ {
+ ibfd->flags |= BFD_NO_SECTION_HEADER;
+ strip_symbols = STRIP_ALL;
+ merge_notes = TRUE;
+ }
+
+ res = copy_object_1 (ibfd, obfd, input_arch);
+
+ strip_symbols = saved_strip_symbols;
+ merge_notes = saved_merge_notes;
+
+ return res;
+}
+
/* Read each archive element in turn from IBFD, copy the
contents to temp file, and keep the temp file handle.
If 'force_output_target' is TRUE then make sure that
@@ -4671,6 +4714,9 @@ strip_main (int argc, char *argv[])
case OPTION_REMOVE_RELOCS:
handle_remove_relocations_option (optarg);
break;
+ case OPTION_REMOVE_SECTION_HEADER:
+ remove_section_header = TRUE;
+ break;
case 's':
strip_symbols = STRIP_ALL;
break;
@@ -5102,6 +5148,10 @@ copy_main (int argc, char *argv[])
handle_remove_relocations_option (optarg);
break;
+ case OPTION_REMOVE_SECTION_HEADER:
+ remove_section_header = TRUE;
+ break;
+
case 'S':
strip_symbols = STRIP_ALL;
break;
diff --git a/ld/NEWS b/ld/NEWS
index 7734d23d5b..79cad101a6 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -1,5 +1,8 @@
-*- text -*-
+* Add command-line option, -z nosectionheader, to omit ELF section header
+ when building an executable or shared library.
+
Changes in 2.34:
* The ld check for "PHDR segment not covered by LOAD segment" is more
diff --git a/ld/emultempl/elf.em b/ld/emultempl/elf.em
index bb7e537530..1ce1af1236 100644
--- a/ld/emultempl/elf.em
+++ b/ld/emultempl/elf.em
@@ -752,6 +752,10 @@ fragment <<EOF
{
link_info.flags_1 |= DF_1_GLOBAUDIT;
}
+ else if (strcmp (optarg, "sectionheader") == 0)
+ config.no_section_header = FALSE;
+ else if (strcmp (optarg, "nosectionheader") == 0)
+ config.no_section_header = TRUE;
EOF
if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
diff --git a/ld/ld.h b/ld/ld.h
index 71fd781267..e969263b3b 100644
--- a/ld/ld.h
+++ b/ld/ld.h
@@ -280,6 +280,9 @@ typedef struct
/* If set, code and non-code sections should never be in one segment. */
bfd_boolean separate_code;
+ /* If set, generation of ELF section header should be suppressed. */
+ bfd_boolean no_section_header;
+
/* The rpath separation character. Usually ':'. */
char rpath_separator;
diff --git a/ld/ld.texi b/ld/ld.texi
index 27343c798f..54ba174cc2 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -1295,6 +1295,12 @@ relocation, if supported. Specifying @samp{common-page-size} smaller
than the system page size will render this protection ineffective.
Don't create an ELF @code{PT_GNU_RELRO} segment if @samp{norelro}.
+@item sectionheader
+@itemx nosectionheader
+Generate section header when building an executable or shared library.
+Don't generate section header if @samp{sectionheader} is used.
+@option{sectionheader} is the default.
+
@item separate-code
@itemx noseparate-code
Create separate code @code{PT_LOAD} segment header in the object. This
diff --git a/ld/ldlang.c b/ld/ldlang.c
index 63f9d182ea..df187c21bf 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -3432,6 +3432,10 @@ ldlang_open_output (lang_statement_union_type *statement)
link_info.output_bfd->flags |= BFD_TRADITIONAL_FORMAT;
else
link_info.output_bfd->flags &= ~BFD_TRADITIONAL_FORMAT;
+ if (config.no_section_header)
+ link_info.output_bfd->flags |= BFD_NO_SECTION_HEADER;
+ else
+ link_info.output_bfd->flags &= ~BFD_NO_SECTION_HEADER;
break;
case lang_target_statement_enum:
diff --git a/ld/lexsup.c b/ld/lexsup.c
index 3d15cc491d..621c8d6605 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -1676,6 +1676,14 @@ parse_args (unsigned argc, char **argv)
break;
}
+ if (config.no_section_header)
+ {
+ if (link_info.type == type_relocatable)
+ einfo (_("%F%P: -r and -z nosectionheader may not be used together\n"));
+ /* -z nosectionheader implies --strip-all. */
+ link_info.strip = strip_all;
+ }
+
if (!bfd_link_dll (&link_info))
{
if (command_line.filter_shlib)
@@ -1879,6 +1887,10 @@ elf_static_list_options (FILE *file)
-z noexecstack Mark executable as not requiring executable stack\n"));
fprintf (file, _("\
-z globalaudit Mark executable requiring global auditing\n"));
+ fprintf (file, _("\
+ -z sectionheader Generate section header (default)\n"));
+ fprintf (file, _("\
+ -z nosectionheader Do not generate section header\n"));
}
static void
--
2.24.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 2/7] bfd: Reconstruct dynamic symbol table from PT_DYNAMIC segment
2020-03-08 23:42 [PATCH 0/7] ELF: Don't require section header on ELF objects H.J. Lu
2020-03-08 23:42 ` [PATCH 1/7] " H.J. Lu
@ 2020-03-08 23:42 ` H.J. Lu
2020-03-08 23:42 ` [PATCH 3/7] readelf: Compute dynamic symbol table size from hash table H.J. Lu
` (5 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: H.J. Lu @ 2020-03-08 23:42 UTC (permalink / raw)
To: binutils
When there is no section header in an executable or shared library, we
reconstruct dynamic symbol table from the PT_DYNAMIC segment which
contains DT_HASH/DT_GNU_HASH/DT_MIPS_XHASH, DT_STRTAB, DT_SYMTAB,
DT_STRSZ and DT_SYMENT entries, which can be used to reconstruct dynamic
symbol table. For DT_HASH, the number of dynamic symbol table entries
equals the number of chains. For DT_GNU_HASH/DT_MIPS_XHASH, only
defined symbols with non-STB_LOCAL indings are in hash table. Since
in dynamic symbol table, all symbols with STB_LOCAL binding are placed
before symbols with other bindings and all undefined symbols are placed
before defined ones, the highest symbol index in DT_GNU_HASH and
DT_MIPS_XHASH is the highest dynamic symbol table index.
dt_symtab, dt_symtab_count and dt_strtab are added to elf_obj_tdata to
store dynamic symbol table information.
PR ld/25617
* elf-bfd.h (elf_obj_tdata): Add dt_symtab, dt_symtab_count and
dt_strtab.
(elf_use_dt_symtab_p): New.
(_bfd_elf_get_dynamic_symbols): Likewise.
* elf.c (bfd_elf_get_elf_syms): Use dynamic symbol table if
neeeded.
(_bfd_elf_get_dynamic_symtab_upper_bound): Likewise.
(offset_from_vma): New function.
(get_hash_table_data): Likewise.
(_bfd_elf_get_dynamic_symbols): Likewise.
* elfcode.h (elf_object_p): Call _bfd_elf_get_dynamic_symbols
to reconstruct dynamic symbol table from PT_DYNAMIC segment if
there is no section header.
(elf_slurp_symbol_table): Use dynamic symbol table if neeeded.
Don't free isymbuf when dynamic symbol table is used.
* elflink.c (elf_link_is_defined_archive_symbol): Likewise.
(elf_link_add_object_symbols): Likewise.
---
bfd/elf-bfd.h | 8 +
bfd/elf.c | 443 ++++++++++++++++++++++++++++++++++++++++++++++++++
bfd/elfcode.h | 133 +++++++++++++--
bfd/elflink.c | 148 +++++++++++------
4 files changed, 673 insertions(+), 59 deletions(-)
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 5d9e0fedcd..b66dcaa010 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1876,6 +1876,9 @@ struct elf_obj_tdata
Elf_Internal_Shdr dynversym_hdr;
Elf_Internal_Shdr dynverref_hdr;
Elf_Internal_Shdr dynverdef_hdr;
+ Elf_Internal_Sym *dt_symtab;
+ bfd_size_type dt_symtab_count;
+ char *dt_strtab;
elf_section_list * symtab_shndx_list;
bfd_vma gp; /* The gp value */
unsigned int gp_size; /* The gp size */
@@ -2030,6 +2033,7 @@ struct elf_obj_tdata
#define elf_dyn_lib_class(bfd) (elf_tdata(bfd) -> dyn_lib_class)
#define elf_bad_symtab(bfd) (elf_tdata(bfd) -> bad_symtab)
#define elf_flags_init(bfd) (elf_tdata(bfd) -> o->flags_init)
+#define elf_use_dt_symtab_p(bfd) (elf_tdata(bfd) -> dt_symtab_count != 0)
#define elf_known_obj_attributes(bfd) (elf_tdata (bfd) -> known_obj_attributes)
#define elf_other_obj_attributes(bfd) (elf_tdata (bfd) -> other_obj_attributes)
#define elf_known_obj_attributes_proc(bfd) \
@@ -2403,6 +2407,10 @@ extern bfd_reloc_status_type bfd_elf_perform_complex_relocation
extern bfd_boolean _bfd_elf_setup_sections
(bfd *);
+extern bfd_boolean _bfd_elf_get_dynamic_symbols
+ (bfd *, Elf_Internal_Phdr *, Elf_Internal_Phdr *, size_t,
+ bfd_size_type);
+
extern struct bfd_link_hash_entry *bfd_elf_define_start_stop
(struct bfd_link_info *, const char *, asection *);
diff --git a/bfd/elf.c b/bfd/elf.c
index e6db2ff64d..a2e78ded89 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -405,6 +405,17 @@ bfd_elf_get_elf_syms (bfd *ibfd,
if (symcount == 0)
return intsym_buf;
+ if (elf_use_dt_symtab_p (ibfd))
+ {
+ /* Use dynamic symbol table. */
+ if (elf_tdata (ibfd)->dt_symtab_count != (symcount + symoffset))
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return NULL;
+ }
+ return elf_tdata (ibfd)->dt_symtab + symoffset;
+ }
+
/* Normal syms might have section extension entries. */
shndx_hdr = NULL;
if (elf_symtab_shndx_list (ibfd) != NULL)
@@ -1881,6 +1892,431 @@ _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
return FALSE;
}
+/* Find the file offset corresponding to VMA by using the program
+ headers. */
+
+static file_ptr
+offset_from_vma (Elf_Internal_Phdr *phdrs, size_t phnum, bfd_vma vma,
+ bfd_vma size)
+{
+ Elf_Internal_Phdr *seg;
+ size_t i;
+
+ for (seg = phdrs, i = 0; i < phnum; ++seg, ++i)
+ if (seg->p_type == PT_LOAD
+ && vma >= (seg->p_vaddr & -seg->p_align)
+ && vma + size <= seg->p_vaddr + seg->p_filesz)
+ return (file_ptr) (vma - seg->p_vaddr + seg->p_offset);
+
+ bfd_set_error (bfd_error_invalid_operation);
+ return (file_ptr) -1;
+}
+
+/* Convert hash table to internal form. */
+
+static bfd_vma *
+get_hash_table_data (bfd *abfd, bfd_size_type number,
+ unsigned int ent_size, bfd_size_type filesize)
+{
+ unsigned char *e_data = NULL;
+ bfd_vma *i_data = NULL;
+ bfd_size_type size;
+
+ if (ent_size != 4 && ent_size != 8)
+ return NULL;
+
+ /* If the size_t type is smaller than the bfd_size_type, eg because
+ you are building a 32-bit tool on a 64-bit host, then make sure
+ that when (number) is cast to (size_t) no information is lost. */
+ if (sizeof (size_t) < sizeof (bfd_size_type)
+ && (bfd_size_type) ((size_t) number) != number)
+ {
+ bfd_set_error (bfd_error_file_too_big);
+ return NULL;
+ }
+
+ size = ent_size * number;
+ /* Be kind to memory chekers (eg valgrind, address sanitizer) by not
+ attempting to allocate memory when the read is bound to fail. */
+ if (size > filesize
+ || number >= ~(size_t) 0 / ent_size
+ || number >= ~(size_t) 0 / sizeof (*i_data))
+ {
+ bfd_set_error (bfd_error_file_too_big);
+ return NULL;
+ }
+
+ e_data = _bfd_malloc_and_read (abfd, size, size);
+ if (e_data == NULL)
+ return NULL;
+
+ i_data = (bfd_vma *) bfd_malloc (number * sizeof (*i_data));
+ if (i_data == NULL)
+ {
+ free (e_data);
+ return NULL;
+ }
+
+ if (ent_size == 4)
+ while (number--)
+ i_data[number] = bfd_get_32 (abfd, e_data + number * ent_size);
+ else
+ while (number--)
+ i_data[number] = bfd_get_64 (abfd, e_data + number * ent_size);
+
+ free (e_data);
+ return i_data;
+}
+
+/* Address of .MIPS.xhash section. FIXME: What is the best way to
+ support DT_MIPS_XHASH? */
+#define DT_MIPS_XHASH 0x70000036
+
+/* Reconstruct dynamic symbol table from PT_DYNAMIC segment. */
+
+bfd_boolean
+_bfd_elf_get_dynamic_symbols (bfd *abfd, Elf_Internal_Phdr *phdr,
+ Elf_Internal_Phdr *phdrs, size_t phnum,
+ bfd_size_type filesize)
+{
+ bfd_byte *extdyn, *extdynend;
+ size_t extdynsize;
+ void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);
+ bfd_boolean (*swap_symbol_in) (bfd *, const void *, const void *,
+ Elf_Internal_Sym *);
+ Elf_Internal_Dyn dyn;
+ bfd_vma dt_hash = 0;
+ bfd_vma dt_gnu_hash = 0;
+ bfd_vma dt_mips_xhash = 0;
+ bfd_vma dt_strtab = 0;
+ bfd_vma dt_symtab = 0;
+ bfd_vma dt_strsz = 0;
+ bfd_byte *dynbuf = NULL;
+ char *strbuf = NULL;
+ bfd_vma *gnubuckets = NULL;
+ bfd_vma *gnuchains = NULL;
+ bfd_vma *mipsxlat = NULL;
+ file_ptr saved_filepos, filepos;
+ bfd_boolean res = FALSE;
+ bfd_size_type amt;
+ bfd_byte *esymbuf = NULL, *esym;
+ bfd_size_type symcount;
+ Elf_Internal_Sym *isymbuf = NULL;
+ Elf_Internal_Sym *isym, *isymend;
+ size_t extsym_size;
+ const struct elf_backend_data *bed;
+
+ /* Return TRUE if symbol table is bad. */
+ if (elf_bad_symtab (abfd))
+ return TRUE;
+
+ /* Return TRUE if DT_HASH/DT_GNU_HASH have bee processed before. */
+ if (elf_tdata (abfd)->dt_strtab != NULL)
+ return TRUE;
+
+ bed = get_elf_backend_data (abfd);
+
+ /* Save file position for elf_object_p. */
+ saved_filepos = bfd_tell (abfd);
+
+ if (bfd_seek (abfd, phdr->p_offset, SEEK_SET) != 0)
+ goto error_return;
+
+ dynbuf = _bfd_malloc_and_read (abfd, phdr->p_filesz, phdr->p_filesz);
+ if (dynbuf == NULL)
+ goto error_return;
+
+ extsym_size = bed->s->sizeof_sym;
+ extdynsize = bed->s->sizeof_dyn;
+ swap_dyn_in = bed->s->swap_dyn_in;
+
+ extdyn = dynbuf;
+ if (phdr->p_filesz < extdynsize)
+ goto error_return;
+ extdynend = extdyn + phdr->p_filesz;
+ for (; extdyn <= (extdynend - extdynsize); extdyn += extdynsize)
+ {
+ swap_dyn_in (abfd, extdyn, &dyn);
+
+ if (dyn.d_tag == DT_NULL)
+ break;
+
+ switch (dyn.d_tag)
+ {
+ case DT_HASH:
+ dt_hash = dyn.d_un.d_val;
+ break;
+ case DT_GNU_HASH:
+ if (bed->elf_machine_code != EM_MIPS
+ && bed->elf_machine_code != EM_MIPS_RS3_LE)
+ dt_gnu_hash = dyn.d_un.d_val;
+ break;
+ case DT_STRTAB:
+ dt_strtab = dyn.d_un.d_val;
+ break;
+ case DT_SYMTAB:
+ dt_symtab = dyn.d_un.d_val;
+ break;
+ case DT_STRSZ:
+ dt_strsz = dyn.d_un.d_val;
+ break;
+ case DT_SYMENT:
+ if (dyn.d_un.d_val != extsym_size)
+ goto error_return;
+ break;
+ default:
+ if (dyn.d_tag == DT_MIPS_XHASH
+ && (bed->elf_machine_code == EM_MIPS
+ || bed->elf_machine_code == EM_MIPS_RS3_LE))
+ {
+ dt_gnu_hash = dyn.d_un.d_val;
+ dt_mips_xhash = dyn.d_un.d_val;
+ }
+ break;
+ }
+ }
+
+ /* Check if we can reconstruct dynamic symbol table from PT_DYNAMIC
+ segment. */
+ if ((!dt_hash && !dt_gnu_hash)
+ || !dt_strtab
+ || !dt_symtab
+ || !dt_strsz)
+ goto error_return;
+
+ /* Get dynamic string stable. */
+ filepos = offset_from_vma (phdrs, phnum, dt_strtab, dt_strsz);
+ if (filepos == (file_ptr) -1
+ || bfd_seek (abfd, filepos, SEEK_SET) != 0)
+ goto error_return;
+
+ /* Dynamic string stable must be valid until ABFD is closed. */
+ strbuf = (char *) _bfd_alloc_and_read (abfd, dt_strsz, dt_strsz);
+ if (strbuf == NULL)
+ goto error_return;
+
+ /* Get the real symbol count from DT_HASH or DT_GNU_HASH. Prefer
+ DT_HASH since it is simpler than DT_GNU_HASH. */
+ if (dt_hash)
+ {
+ unsigned char nb[16];
+ unsigned int hash_ent_size;
+
+ switch (bed->elf_machine_code)
+ {
+ case EM_ALPHA:
+ case EM_S390:
+ case EM_S390_OLD:
+ if (bed->s->elfclass == ELFCLASS64)
+ {
+ hash_ent_size = 8;
+ break;
+ }
+ /* FALLTHROUGH */
+ default:
+ hash_ent_size = 4;
+ break;
+ }
+
+ filepos = offset_from_vma (phdrs, phnum, dt_hash, sizeof (nb));
+ if (filepos == (file_ptr) -1
+ || bfd_seek (abfd, filepos, SEEK_SET) != 0
+ || (bfd_bread (nb, 2 * hash_ent_size, abfd)
+ != (2 * hash_ent_size)))
+ goto error_return;
+
+ /* The number of dynamic symbol table entries equals the number
+ of chains. */
+ if (hash_ent_size == 8)
+ symcount = bfd_get_64 (abfd, nb + hash_ent_size);
+ else
+ symcount = bfd_get_32 (abfd, nb + hash_ent_size);
+ }
+ else
+ {
+ /* For DT_GNU_HASH, only defined symbols with non-STB_LOCAL
+ bindings are in hash table. Since in dynamic symbol table,
+ all symbols with STB_LOCAL binding are placed before symbols
+ with other bindings and all undefined symbols are placed
+ before defined ones, the highest symbol index in DT_GNU_HASH
+ is the highest dynamic symbol table index. */
+ unsigned char nb[16];
+ bfd_vma ngnubuckets;
+ bfd_vma gnusymidx;
+ size_t i, ngnuchains;
+ bfd_vma maxchain = 0xffffffff, bitmaskwords;
+ bfd_vma buckets_vma;
+
+ filepos = offset_from_vma (phdrs, phnum, dt_gnu_hash,
+ sizeof (nb));
+ if (filepos == (file_ptr) -1
+ || bfd_seek (abfd, filepos, SEEK_SET) != 0
+ || bfd_bread (nb, sizeof (nb), abfd) != sizeof (nb))
+ goto error_return;
+
+ ngnubuckets = bfd_get_32 (abfd, nb);
+ gnusymidx = bfd_get_32 (abfd, nb + 4);
+ bitmaskwords = bfd_get_32 (abfd, nb + 8);
+ buckets_vma = dt_gnu_hash + 16;
+ if (bed->s->elfclass == ELFCLASS32)
+ buckets_vma += bitmaskwords * 4;
+ else
+ buckets_vma += bitmaskwords * 8;
+ filepos = offset_from_vma (phdrs, phnum, buckets_vma, 4);
+ if (filepos == (file_ptr) -1
+ || bfd_seek (abfd, filepos, SEEK_SET) != 0)
+ goto error_return;
+
+ gnubuckets = get_hash_table_data (abfd, ngnubuckets, 4, filesize);
+ if (gnubuckets == NULL)
+ goto error_return;
+
+ for (i = 0; i < ngnubuckets; i++)
+ if (gnubuckets[i] != 0)
+ {
+ if (gnubuckets[i] < gnusymidx)
+ goto error_return;
+
+ if (maxchain == 0xffffffff || gnubuckets[i] > maxchain)
+ maxchain = gnubuckets[i];
+ }
+
+ if (maxchain == 0xffffffff)
+ goto error_return;
+
+ maxchain -= gnusymidx;
+ filepos = offset_from_vma (phdrs, phnum,
+ (buckets_vma +
+ 4 * (ngnubuckets + maxchain)),
+ 4);
+ if (filepos == (file_ptr) -1
+ || bfd_seek (abfd, filepos, SEEK_SET) != 0)
+ goto error_return;
+
+ do
+ {
+ if (bfd_bread (nb, 4, abfd) != 4)
+ goto error_return;
+ ++maxchain;
+ if (maxchain == 0)
+ goto error_return;
+ }
+ while ((bfd_get_32 (abfd, nb) & 1) == 0);
+
+ filepos = offset_from_vma (phdrs, phnum,
+ (buckets_vma + 4 * ngnubuckets),
+ 4);
+ if (filepos == (file_ptr) -1
+ || bfd_seek (abfd, filepos, SEEK_SET) != 0)
+ goto error_return;
+
+ gnuchains = get_hash_table_data (abfd, maxchain, 4, filesize);
+ if (gnubuckets == NULL)
+ goto error_return;
+ ngnuchains = maxchain;
+
+ if (dt_mips_xhash)
+ {
+ filepos = offset_from_vma (phdrs, phnum,
+ (buckets_vma
+ + 4 * (ngnubuckets + maxchain)),
+ 4);
+ if (filepos == (file_ptr) -1
+ || bfd_seek (abfd, filepos, SEEK_SET) != 0)
+ goto error_return;
+
+ mipsxlat = get_hash_table_data (abfd, maxchain, 4, filesize);
+ if (mipsxlat == NULL)
+ goto error_return;
+ }
+
+ symcount = 0;
+ for (i = 0; i < ngnubuckets; ++i)
+ if (gnubuckets[i] != 0)
+ {
+ bfd_vma si = gnubuckets[i];
+ bfd_vma off = si - gnusymidx;
+ do
+ {
+ if (mipsxlat)
+ {
+ if (mipsxlat[off] >= symcount)
+ symcount = mipsxlat[off] + 1;
+ }
+ else
+ {
+ if (si >= symcount)
+ symcount = si + 1;
+ }
+ si++;
+ }
+ while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
+ }
+ }
+
+ /* Swap in dynamic symbol stable. */
+ if (_bfd_mul_overflow (symcount, extsym_size, &amt))
+ {
+ bfd_set_error (bfd_error_file_too_big);
+ goto error_return;
+ }
+
+ filepos = offset_from_vma (phdrs, phnum, dt_symtab, amt);
+ if (filepos == (file_ptr) -1
+ || bfd_seek (abfd, filepos, SEEK_SET) != 0)
+ goto error_return;
+ esymbuf = _bfd_malloc_and_read (abfd, amt, amt);
+ if (esymbuf == NULL)
+ goto error_return;
+
+ if (_bfd_mul_overflow (symcount, sizeof (Elf_Internal_Sym), &amt))
+ {
+ bfd_set_error (bfd_error_file_too_big);
+ goto error_return;
+ }
+
+ /* Dynamic symbol stable must be valid until ABFD is closed. */
+ isymbuf = (Elf_Internal_Sym *) bfd_alloc (abfd, amt);
+ if (isymbuf == NULL)
+ goto error_return;
+
+ swap_symbol_in = bed->s->swap_symbol_in;
+
+ /* Convert the symbols to internal form. */
+ isymend = isymbuf + symcount;
+ for (esym = esymbuf, isym = isymbuf;
+ isym < isymend;
+ esym += extsym_size, isym++)
+ if (!swap_symbol_in (abfd, esym, NULL, isym)
+ || isym->st_name >= dt_strsz)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ goto error_return;
+ }
+
+ elf_tdata (abfd)->dt_strtab = strbuf;
+ elf_tdata (abfd)->dt_symtab = isymbuf;
+ elf_tdata (abfd)->dt_symtab_count = symcount;
+
+ res = TRUE;
+
+ error_return:
+ /* Restore file position for elf_object_p. */
+ if (bfd_seek (abfd, saved_filepos, SEEK_SET) != 0)
+ res = FALSE;
+ if (dynbuf != NULL)
+ free (dynbuf);
+ if (esymbuf != NULL)
+ free (esymbuf);
+ if (gnubuckets != NULL)
+ free (gnubuckets);
+ if (gnuchains != NULL)
+ free (gnuchains);
+ if (mipsxlat != NULL)
+ free (mipsxlat);
+ return res;
+}
+
/* Get version string. */
const char *
@@ -8415,6 +8851,11 @@ _bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd)
if (elf_dynsymtab (abfd) == 0)
{
+ /* Check if there is dynamic symbol table. */
+ symcount = elf_tdata (abfd)->dt_symtab_count;
+ if (symcount)
+ goto compute_symtab_size;
+
bfd_set_error (bfd_error_invalid_operation);
return -1;
}
@@ -8425,6 +8866,8 @@ _bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd)
bfd_set_error (bfd_error_file_too_big);
return -1;
}
+
+ compute_symtab_size:
symtab_size = (symcount + 1) * (sizeof (asymbol *));
if (symcount > 0)
symtab_size -= sizeof (asymbol *);
diff --git a/bfd/elfcode.h b/bfd/elfcode.h
index 4dde24e02a..40289ca7ce 100644
--- a/bfd/elfcode.h
+++ b/bfd/elfcode.h
@@ -820,6 +820,21 @@ elf_object_p (bfd *abfd)
if (bfd_bread (&x_phdr, sizeof x_phdr, abfd) != sizeof x_phdr)
goto got_no_match;
elf_swap_phdr_in (abfd, &x_phdr, i_phdr);
+ if (i_phdr->p_filesz != 0)
+ {
+ if ((i_phdr->p_offset + i_phdr->p_filesz) > filesize)
+ goto got_no_match;
+ /* Try to reconstruct dynamic symbol table from PT_DYNAMIC
+ segment if there is no section header. */
+ if (i_phdr->p_type == PT_DYNAMIC
+ && i_ehdrp->e_shstrndx == 0
+ && i_ehdrp->e_shoff == 0
+ && !_bfd_elf_get_dynamic_symbols (abfd, i_phdr,
+ elf_tdata (abfd)->phdr,
+ i_ehdrp->e_phnum,
+ filesize))
+ goto got_no_match;
+ }
}
}
@@ -1189,6 +1204,7 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
Elf_External_Versym *xverbuf = NULL;
const struct elf_backend_data *ebd;
size_t amt;
+ asection *sec;
/* Read each raw ELF symbol, converting from external ELF form to
internal ELF form, and then using the information to create a
@@ -1223,7 +1239,9 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
}
ebd = get_elf_backend_data (abfd);
- symcount = hdr->sh_size / sizeof (Elf_External_Sym);
+ symcount = elf_tdata (abfd)->dt_symtab_count;
+ if (symcount == 0)
+ symcount = hdr->sh_size / sizeof (Elf_External_Sym);
if (symcount == 0)
sym = symbase = NULL;
else
@@ -1279,7 +1297,11 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
memcpy (&sym->internal_elf_sym, isym, sizeof (Elf_Internal_Sym));
sym->symbol.the_bfd = abfd;
- sym->symbol.name = bfd_elf_sym_name (abfd, hdr, isym, NULL);
+ if (elf_use_dt_symtab_p (abfd))
+ sym->symbol.name = (elf_tdata (abfd)->dt_strtab
+ + isym->st_name);
+ else
+ sym->symbol.name = bfd_elf_sym_name (abfd, hdr, isym, NULL);
sym->symbol.value = isym->st_value;
if (isym->st_shndx == SHN_UNDEF)
@@ -1313,7 +1335,7 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
moment) about the alignment. */
sym->symbol.value = isym->st_size;
}
- else
+ else if (!elf_use_dt_symtab_p (abfd))
{
sym->symbol.section
= bfd_section_from_elf_index (abfd, isym->st_shndx);
@@ -1329,11 +1351,6 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
}
}
- /* If this is a relocatable file, then the symbol value is
- already section relative. */
- if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
- sym->symbol.value -= sym->symbol.section->vma;
-
switch (ELF_ST_BIND (isym->st_info))
{
case STB_LOCAL:
@@ -1355,23 +1372,87 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
{
case STT_SECTION:
sym->symbol.flags |= BSF_SECTION_SYM | BSF_DEBUGGING;
+ if (sym->symbol.section == NULL
+ && elf_use_dt_symtab_p (abfd))
+ sym->symbol.section = bfd_abs_section_ptr;
break;
case STT_FILE:
sym->symbol.flags |= BSF_FILE | BSF_DEBUGGING;
+ if (sym->symbol.section == NULL
+ && elf_use_dt_symtab_p (abfd))
+ sym->symbol.section = bfd_abs_section_ptr;
break;
case STT_FUNC:
sym->symbol.flags |= BSF_FUNCTION;
+ if (sym->symbol.section == NULL
+ && elf_use_dt_symtab_p (abfd))
+ {
+ sec = bfd_get_section_by_name (abfd, ".text");
+ if (sec == NULL)
+ {
+ flagword flags = (SEC_ALLOC
+ | SEC_CODE
+ | SEC_LOAD
+ | SEC_LINKER_CREATED);
+ sec = bfd_make_section_with_flags (abfd,
+ ".text",
+ flags);
+ if (sec == NULL)
+ goto error_return;
+ }
+ sym->symbol.section = sec;
+ }
break;
case STT_COMMON:
/* FIXME: Do we have to put the size field into the value field
as we do with symbols in SHN_COMMON sections (see above) ? */
sym->symbol.flags |= BSF_ELF_COMMON;
+ if (sym->symbol.section == NULL
+ && elf_use_dt_symtab_p (abfd))
+ sym->symbol.section = bfd_com_section_ptr;
/* Fall through. */
case STT_OBJECT:
sym->symbol.flags |= BSF_OBJECT;
+ if (sym->symbol.section == NULL
+ && elf_use_dt_symtab_p (abfd))
+ {
+ sec = bfd_get_section_by_name (abfd, ".data");
+ if (sec == NULL)
+ {
+ flagword flags = (SEC_ALLOC
+ | SEC_DATA
+ | SEC_LOAD
+ | SEC_LINKER_CREATED);
+ sec = bfd_make_section_with_flags (abfd,
+ ".data",
+ flags);
+ if (sec == NULL)
+ goto error_return;
+ }
+ sym->symbol.section = sec;
+ }
break;
case STT_TLS:
sym->symbol.flags |= BSF_THREAD_LOCAL;
+ if (sym->symbol.section == NULL
+ && elf_use_dt_symtab_p (abfd))
+ {
+ sec = bfd_get_section_by_name (abfd, ".tdata");
+ if (sec == NULL)
+ {
+ flagword flags = (SEC_ALLOC
+ | SEC_DATA
+ | SEC_THREAD_LOCAL
+ | SEC_LOAD
+ | SEC_LINKER_CREATED);
+ sec = bfd_make_section_with_flags (abfd,
+ ".tdata",
+ flags);
+ if (sec == NULL)
+ goto error_return;
+ }
+ sym->symbol.section = sec;
+ }
break;
case STT_RELC:
sym->symbol.flags |= BSF_RELC;
@@ -1381,9 +1462,37 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
break;
case STT_GNU_IFUNC:
sym->symbol.flags |= BSF_GNU_INDIRECT_FUNCTION;
+ if (sym->symbol.section == NULL
+ && elf_use_dt_symtab_p (abfd))
+ {
+ sec = bfd_get_section_by_name (abfd, ".text");
+ if (sec == NULL)
+ {
+ flagword flags = (SEC_ALLOC
+ | SEC_CODE
+ | SEC_LOAD
+ | SEC_LINKER_CREATED);
+ sec = bfd_make_section_with_flags (abfd,
+ ".text",
+ flags);
+ if (sec == NULL)
+ goto error_return;
+ }
+ sym->symbol.section = sec;
+ }
+ break;
+ default:
+ if (sym->symbol.section == NULL
+ && elf_use_dt_symtab_p (abfd))
+ sym->symbol.section = bfd_abs_section_ptr;
break;
}
+ /* If this is a relocatable file, then the symbol value is
+ already section relative. */
+ if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
+ sym->symbol.value -= sym->symbol.section->vma;
+
if (dynamic)
sym->symbol.flags |= BSF_DYNAMIC;
@@ -1426,14 +1535,18 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic)
if (xverbuf != NULL)
free (xverbuf);
- if (isymbuf != NULL && hdr->contents != (unsigned char *) isymbuf)
+ if (isymbuf != NULL
+ && hdr->contents != (unsigned char *) isymbuf
+ && !elf_use_dt_symtab_p (abfd))
free (isymbuf);
return symcount;
error_return:
if (xverbuf != NULL)
free (xverbuf);
- if (isymbuf != NULL && hdr->contents != (unsigned char *) isymbuf)
+ if (isymbuf != NULL
+ && hdr->contents != (unsigned char *) isymbuf
+ && !elf_use_dt_symtab_p (abfd))
free (isymbuf);
return -1;
}
diff --git a/bfd/elflink.c b/bfd/elflink.c
index c04712a10f..900c0ecdf1 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -3394,39 +3394,61 @@ elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef)
if (! bfd_check_format (abfd, bfd_object))
return FALSE;
- /* Select the appropriate symbol table. If we don't know if the
- object file is an IR object, give linker LTO plugin a chance to
- get the correct symbol table. */
- if (abfd->plugin_format == bfd_plugin_yes
-#if BFD_SUPPORTS_PLUGINS
- || (abfd->plugin_format == bfd_plugin_unknown
- && bfd_link_plugin_object_p (abfd))
-#endif
- )
- {
- /* Use the IR symbol table if the object has been claimed by
- plugin. */
- abfd = abfd->plugin_dummy_bfd;
- hdr = &elf_tdata (abfd)->symtab_hdr;
- }
- else if ((abfd->flags & DYNAMIC) == 0 || elf_dynsymtab (abfd) == 0)
- hdr = &elf_tdata (abfd)->symtab_hdr;
- else
- hdr = &elf_tdata (abfd)->dynsymtab_hdr;
-
- symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
-
- /* The sh_info field of the symtab header tells us where the
- external symbols start. We don't care about the local symbols. */
- if (elf_bad_symtab (abfd))
+ extsymcount = elf_tdata (abfd)->dt_symtab_count;
+ if (extsymcount)
{
- extsymcount = symcount;
+ /* Find the first global symbol. */
+ BFD_ASSERT (!elf_bad_symtab (abfd));
+ hdr = NULL;
extsymoff = 0;
+ isym = elf_tdata (abfd)->dt_symtab;
+ isymend = isym + extsymcount;
+ for (; isym < isymend; isym++)
+ if (ELF_ST_BIND (isym->st_info) == STB_LOCAL)
+ {
+ extsymcount--;
+ extsymoff++;
+ }
+ else
+ break;
}
else
{
- extsymcount = symcount - hdr->sh_info;
- extsymoff = hdr->sh_info;
+ /* Select the appropriate symbol table. If we don't know if the
+ object file is an IR object, give linker LTO plugin a chance to
+ get the correct symbol table. */
+ if (abfd->plugin_format == bfd_plugin_yes
+#if BFD_SUPPORTS_PLUGINS
+ || (abfd->plugin_format == bfd_plugin_unknown
+ && bfd_link_plugin_object_p (abfd))
+#endif
+ )
+ {
+ /* Use the IR symbol table if the object has been claimed by
+ plugin. */
+ abfd = abfd->plugin_dummy_bfd;
+ hdr = &elf_tdata (abfd)->symtab_hdr;
+ }
+ else if ((abfd->flags & DYNAMIC) == 0 || elf_dynsymtab (abfd) == 0)
+ hdr = &elf_tdata (abfd)->symtab_hdr;
+ else
+ hdr = &elf_tdata (abfd)->dynsymtab_hdr;
+
+ symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
+
+ /* The sh_info field of the symtab header tells us where the
+ external symbols start. We don't care about the local
+ symbols. */
+ if (elf_bad_symtab (abfd))
+ {
+ extsymcount = symcount;
+ extsymoff = 0;
+ }
+ else
+ {
+ extsymcount = symcount - hdr->sh_info;
+ extsymoff = hdr->sh_info;
+ }
}
if (extsymcount == 0)
@@ -3444,8 +3466,11 @@ elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef)
{
const char *name;
- name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
- isym->st_name);
+ if (hdr)
+ name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
+ isym->st_name);
+ else
+ name = elf_tdata (abfd)->dt_strtab + isym->st_name;
if (name == NULL)
break;
@@ -3456,7 +3481,8 @@ elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef)
}
}
- free (isymbuf);
+ if (!elf_use_dt_symtab_p (abfd))
+ free (isymbuf);
return result;
}
@@ -4276,25 +4302,46 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
will only see the .dynsym symbol table, so there is no reason to
look at .symtab for a dynamic object. */
- if (! dynamic || elf_dynsymtab (abfd) == 0)
- hdr = &elf_tdata (abfd)->symtab_hdr;
- else
- hdr = &elf_tdata (abfd)->dynsymtab_hdr;
-
- symcount = hdr->sh_size / bed->s->sizeof_sym;
-
- /* The sh_info field of the symtab header tells us where the
- external symbols start. We don't care about the local symbols at
- this point. */
- if (elf_bad_symtab (abfd))
+ extsymcount = elf_tdata (abfd)->dt_symtab_count;
+ if (extsymcount)
{
- extsymcount = symcount;
+ /* Find the first global symbol. */
+ BFD_ASSERT (!elf_bad_symtab (abfd));
+ hdr = NULL;
extsymoff = 0;
+ isym = elf_tdata (abfd)->dt_symtab;
+ isymend = isym + extsymcount;
+ for (; isym < isymend; isym++)
+ if (ELF_ST_BIND (isym->st_info) == STB_LOCAL)
+ {
+ extsymcount--;
+ extsymoff++;
+ }
+ else
+ break;
}
else
{
- extsymcount = symcount - hdr->sh_info;
- extsymoff = hdr->sh_info;
+ if (! dynamic || elf_dynsymtab (abfd) == 0)
+ hdr = &elf_tdata (abfd)->symtab_hdr;
+ else
+ hdr = &elf_tdata (abfd)->dynsymtab_hdr;
+
+ symcount = hdr->sh_size / bed->s->sizeof_sym;
+
+ /* The sh_info field of the symtab header tells us where the
+ external symbols start. We don't care about the local
+ symbols at this point. */
+ if (elf_bad_symtab (abfd))
+ {
+ extsymcount = symcount;
+ extsymoff = 0;
+ }
+ else
+ {
+ extsymcount = symcount - hdr->sh_info;
+ extsymoff = hdr->sh_info;
+ }
}
sym_hash = elf_sym_hashes (abfd);
@@ -4549,8 +4596,11 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
value -= sec->vma;
}
- name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
- isym->st_name);
+ if (hdr)
+ name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
+ isym->st_name);
+ else
+ name = elf_tdata (abfd)->dt_strtab + isym->st_name;
if (name == NULL)
goto error_free_vers;
@@ -5203,7 +5253,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
extversym = NULL;
}
- if (isymbuf != NULL)
+ if (isymbuf != NULL && !elf_use_dt_symtab_p (abfd))
{
free (isymbuf);
isymbuf = NULL;
@@ -5580,7 +5630,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
if (extversym != NULL)
free (extversym);
error_free_sym:
- if (isymbuf != NULL)
+ if (isymbuf != NULL && !elf_use_dt_symtab_p (abfd))
free (isymbuf);
error_return:
return FALSE;
--
2.24.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 3/7] readelf: Compute dynamic symbol table size from hash table
2020-03-08 23:42 [PATCH 0/7] ELF: Don't require section header on ELF objects H.J. Lu
2020-03-08 23:42 ` [PATCH 1/7] " H.J. Lu
2020-03-08 23:42 ` [PATCH 2/7] bfd: Reconstruct dynamic symbol table from PT_DYNAMIC segment H.J. Lu
@ 2020-03-08 23:42 ` H.J. Lu
2020-03-08 23:42 ` [PATCH 4/7] ld: Add a simple test for -z nosectionheader H.J. Lu
` (4 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: H.J. Lu @ 2020-03-08 23:42 UTC (permalink / raw)
To: binutils
When reconstructing dynamic symbol table from the PT_DYNAMIC segment,
compute dynamic symbol table size from hash table. For DT_HASH, the
number of dynamic symbol table entries equals the number of chains.
For DT_GNU_HASH/DT_MIPS_XHASH, only defined symbols with non-STB_LOCAL
indings are in hash table. Since in dynamic symbol table, all symbols
with STB_LOCAL binding are placed before symbols with other bindings
and all undefined symbols are placed before defined ones, the highest
symbol index in DT_GNU_HASH and DT_MIPS_XHASH is the highest dynamic
symbol table index.
Also iterate dynamic symbol table to print each entry so that output
of "readelf -D -s" without section header is similar to "readelf -s"
with section header.
`
binutils/
PR ld/25617
* readelf.c (process_dynamic_section): Use DT_SYMTAB and DT_SYMENT
to reconstruct dynamic symbol table, assuming dynamic symbol table
ends at the end of PT_LOAD segment. Use DT_STRTAB and DT_STRSZ to
reconstruct dynamic string table. Set dynamic_info_DT_MIPS_XHASH
and dynamic_info_DT_GNU_HASH for -D.
(get_symbol_index_type): Don't print "bad section index" when
there is no section header.
(print_dynamic_symbol): Don't print bucket number.
(process_symbol_table): Compute dynamic symbol table size from
hash table and iterate dynamic symbol table to print each entry.
ld/
PR ld/25617
* testsuite/ld-elf/hash.d: Updated.
* testsuite/ld-elf/pr13195.d: Likewise.
* testsuite/ld-elfvsb/hidden2.d: Likewise.
* testsuite/ld-mips-elf/hash2.d: Likewise.
---
binutils/readelf.c | 226 ++++++++++++++++---------------
ld/testsuite/ld-elf/hash.d | 8 +-
ld/testsuite/ld-elf/pr13195.d | 2 +-
ld/testsuite/ld-elfvsb/hidden2.d | 2 +-
ld/testsuite/ld-mips-elf/hash2.d | 8 +-
5 files changed, 125 insertions(+), 121 deletions(-)
diff --git a/binutils/readelf.c b/binutils/readelf.c
index d4756c93b3..b45214d17c 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -9863,102 +9863,103 @@ process_dynamic_section (Filedata * filedata)
/* Find the appropriate symbol table. */
if (dynamic_symbols == NULL)
- {
- for (entry = dynamic_section;
- entry < dynamic_section + dynamic_nent;
- ++entry)
- {
- Elf_Internal_Shdr section;
+ for (entry = dynamic_section;
+ entry < dynamic_section + dynamic_nent;
+ ++entry)
+ {
+ if (entry->d_tag == DT_SYMTAB)
+ dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
- if (entry->d_tag != DT_SYMTAB)
- continue;
+ if (entry->d_tag == DT_SYMENT)
+ dynamic_info[DT_SYMENT] = entry->d_un.d_val;
- dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
+ if (dynamic_info[DT_SYMTAB] && dynamic_info[DT_SYMENT])
+ {
+ Elf_Internal_Phdr *seg;
+ bfd_vma vma = dynamic_info[DT_SYMTAB];
- /* Since we do not know how big the symbol table is,
- we default to reading in the entire file (!) and
- processing that. This is overkill, I know, but it
- should work. */
- section.sh_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
- if ((bfd_size_type) section.sh_offset > filedata->file_size)
- {
- /* See PR 21379 for a reproducer. */
- error (_("Invalid DT_SYMTAB entry: %lx\n"),
- (long) section.sh_offset);
- return FALSE;
- }
+ if (! get_program_headers (filedata))
+ {
+ warn (_("Cannot interpret virtual addresses without program headers.\n"));
+ break;
+ }
- if (archive_file_offset != 0)
- section.sh_size = archive_file_size - section.sh_offset;
- else
- section.sh_size = filedata->file_size - section.sh_offset;
+ for (seg = filedata->program_headers;
+ seg < filedata->program_headers + filedata->file_header.e_phnum;
+ ++seg)
+ {
+ if (seg->p_type != PT_LOAD)
+ continue;
- if (is_32bit_elf)
- section.sh_entsize = sizeof (Elf32_External_Sym);
- else
- section.sh_entsize = sizeof (Elf64_External_Sym);
- section.sh_name = filedata->string_table_length;
+ if ((seg->p_offset + seg->p_filesz)
+ > filedata->file_size)
+ {
+ /* See PR 21379 for a reproducer. */
+ error (_("Invalid PT_LOAD entry\n"));
+ return FALSE;
+ }
- if (dynamic_symbols != NULL)
- {
- error (_("Multiple dynamic symbol table sections found\n"));
- free (dynamic_symbols);
- }
- dynamic_symbols = GET_ELF_SYMBOLS (filedata, §ion, & num_dynamic_syms);
- if (num_dynamic_syms < 1)
- {
- error (_("Unable to determine the number of symbols to load\n"));
- continue;
- }
- }
- }
+ if (vma >= (seg->p_vaddr & -seg->p_align)
+ && vma <= seg->p_vaddr + seg->p_filesz)
+ {
+ /* Since we do not know how big the symbol table is,
+ we default to reading in up to the end of PT_LOAD
+ segment and processing that. This is overkill, I
+ know, but it should work. */
+ Elf_Internal_Shdr section;
+ bfd_size_type offset = (vma - seg->p_vaddr
+ + seg->p_offset);
+ bfd_size_type max_symtab_size
+ = seg->p_offset + seg->p_filesz - offset;
+ section.sh_offset = offset;
+ section.sh_size = max_symtab_size;
+ section.sh_entsize = dynamic_info[DT_SYMENT];
+ section.sh_name = filedata->string_table_length;
+ dynamic_symbols = GET_ELF_SYMBOLS (filedata,
+ §ion,
+ & num_dynamic_syms);
+ if (dynamic_symbols == NULL)
+ error (_("Corrupt DT_SYMTAB dynamic entry\n"));
+ }
+ }
+
+ break;
+ }
+ }
/* Similarly find a string table. */
if (dynamic_strings == NULL)
- {
- for (entry = dynamic_section;
- entry < dynamic_section + dynamic_nent;
- ++entry)
- {
- unsigned long offset;
- long str_tab_len;
-
- if (entry->d_tag != DT_STRTAB)
- continue;
-
+ for (entry = dynamic_section;
+ entry < dynamic_section + dynamic_nent;
+ ++entry)
+ {
+ if (entry->d_tag == DT_STRTAB)
dynamic_info[DT_STRTAB] = entry->d_un.d_val;
- /* Since we do not know how big the string table is,
- we default to reading in the entire file (!) and
- processing that. This is overkill, I know, but it
- should work. */
+ if (entry->d_tag == DT_STRSZ)
+ dynamic_info[DT_STRSZ] = entry->d_un.d_val;
- offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
-
- if (archive_file_offset != 0)
- str_tab_len = archive_file_size - offset;
- else
- str_tab_len = filedata->file_size - offset;
-
- if (str_tab_len < 1)
- {
- error
- (_("Unable to determine the length of the dynamic string table\n"));
- continue;
- }
-
- if (dynamic_strings != NULL)
- {
- error (_("Multiple dynamic string tables found\n"));
- free (dynamic_strings);
- }
+ if (dynamic_info[DT_STRTAB] && dynamic_info[DT_STRSZ])
+ {
+ unsigned long offset;
+ bfd_size_type str_tab_len = dynamic_info[DT_STRSZ];
+
+ offset = offset_from_vma (filedata,
+ dynamic_info[DT_STRTAB],
+ str_tab_len);
+ dynamic_strings = (char *) get_data (NULL, filedata, offset, 1,
+ str_tab_len,
+ _("dynamic string table"));
+ if (dynamic_strings == NULL)
+ {
+ error (_("Corrupt DT_STRTAB dynamic entry\n"));
+ break;
+ }
- dynamic_strings = (char *) get_data (NULL, filedata, offset, 1,
- str_tab_len,
- _("dynamic string table"));
- dynamic_strings_length = dynamic_strings == NULL ? 0 : str_tab_len;
- }
- }
+ dynamic_strings_length = str_tab_len;
+ break;
+ }
+ }
/* And find the syminfo section if available. */
if (dynamic_syminfo == NULL)
@@ -10515,6 +10516,14 @@ process_dynamic_section (Filedata * filedata)
putchar ('\n');
}
}
+ else if (do_using_dynamic
+ && (filedata->file_header.e_machine == EM_MIPS
+ || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
+ && entry->d_tag == DT_MIPS_XHASH)
+ {
+ dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
+ dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
+ }
break;
}
}
@@ -11401,7 +11410,8 @@ get_symbol_index_type (Filedata * filedata, unsigned int type)
sprintf (buff, "OS [0x%04x]", type & 0xffff);
else if (type >= SHN_LORESERVE)
sprintf (buff, "RSV[0x%04x]", type & 0xffff);
- else if (type >= filedata->file_header.e_shnum)
+ else if (filedata->file_header.e_shnum != 0
+ && type >= filedata->file_header.e_shnum)
sprintf (buff, _("bad section index[%3d]"), type);
else
sprintf (buff, "%3d", type);
@@ -11471,7 +11481,7 @@ get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_si
}
static void
-print_dynamic_symbol (Filedata * filedata, bfd_vma si, unsigned long hn)
+print_dynamic_symbol (Filedata * filedata, bfd_vma si)
{
Elf_Internal_Sym * psym;
int n;
@@ -11479,7 +11489,7 @@ print_dynamic_symbol (Filedata * filedata, bfd_vma si, unsigned long hn)
n = print_vma (si, DEC_5);
if (n < 5)
fputs (&" "[n], stdout);
- printf (" %3lu: ", hn);
+ fputs (": ", stdout);
if (dynamic_symbols == NULL || si >= num_dynamic_syms)
{
@@ -11915,41 +11925,26 @@ process_symbol_table (Filedata * filedata)
if (dynamic_info[DT_HASH])
{
- bfd_vma si;
- char *visited;
-
printf (_("\nSymbol table for image:\n"));
if (is_32bit_elf)
- printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
+ printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
else
- printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
+ printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
- visited = xcmalloc (nchains, 1);
- memset (visited, 0, nchains);
- for (hn = 0; hn < nbuckets; hn++)
- {
- for (si = buckets[hn]; si > 0; si = chains[si])
- {
- print_dynamic_symbol (filedata, si, hn);
- if (si >= nchains || visited[si])
- {
- error (_("histogram chain is corrupt\n"));
- break;
- }
- visited[si] = 1;
- }
- }
- free (visited);
+ for (hn = 0; hn < nchains; hn++)
+ print_dynamic_symbol (filedata, hn);
}
if (dynamic_info_DT_GNU_HASH)
{
+ unsigned long num_of_syms = 0;
+
printf (_("\nSymbol table of `%s' for image:\n"),
GNU_HASH_SECTION_NAME);
if (is_32bit_elf)
- printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
+ printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
else
- printf (_(" Num Buc: Value Size Type Bind Vis Ndx Name\n"));
+ printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
for (hn = 0; hn < ngnubuckets; ++hn)
if (gnubuckets[hn] != 0)
@@ -11960,13 +11955,22 @@ process_symbol_table (Filedata * filedata)
do
{
if (dynamic_info_DT_MIPS_XHASH)
- print_dynamic_symbol (filedata, mipsxlat[off], hn);
+ {
+ if (mipsxlat[off] >= num_of_syms)
+ num_of_syms = mipsxlat[off] + 1;
+ }
else
- print_dynamic_symbol (filedata, si, hn);
+ {
+ if (si >= num_of_syms)
+ num_of_syms = si + 1;
+ }
si++;
}
while (off < ngnuchains && (gnuchains[off++] & 1) == 0);
}
+
+ for (hn = 0; hn < num_of_syms; hn++)
+ print_dynamic_symbol (filedata, hn);
}
}
else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
diff --git a/ld/testsuite/ld-elf/hash.d b/ld/testsuite/ld-elf/hash.d
index efe675e0c7..a0bebb0b00 100644
--- a/ld/testsuite/ld-elf/hash.d
+++ b/ld/testsuite/ld-elf/hash.d
@@ -9,11 +9,11 @@
#...
+0x[0-9a-z]+ +\(GNU_HASH\) +0x[0-9a-z]+
#...
- +[0-9]+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +NOTYPE +GLOBAL +DEFAULT +[1-9] _start
+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +NOTYPE +GLOBAL +DEFAULT +[1-9] _start
#...
- +[0-9]+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +NOTYPE +GLOBAL +DEFAULT +[1-9] main
+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +NOTYPE +GLOBAL +DEFAULT +[1-9] main
#...
- +[0-9]+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +NOTYPE +GLOBAL +DEFAULT +[1-9] start
+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +NOTYPE +GLOBAL +DEFAULT +[1-9] start
#...
- +[0-9]+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +NOTYPE +GLOBAL +DEFAULT +[1-9] __start
+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +NOTYPE +GLOBAL +DEFAULT +[1-9] __start
#...
diff --git a/ld/testsuite/ld-elf/pr13195.d b/ld/testsuite/ld-elf/pr13195.d
index 8a0f9bd805..fb02e22afa 100644
--- a/ld/testsuite/ld-elf/pr13195.d
+++ b/ld/testsuite/ld-elf/pr13195.d
@@ -5,5 +5,5 @@
# generic linker targets don't support --gc-sections, nor do a bunch of others
#...
- +[0-9]+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +FUNC +GLOBAL +DEFAULT +[1-9]+ foo
+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +FUNC +GLOBAL +DEFAULT +[1-9]+ foo
#pass
diff --git a/ld/testsuite/ld-elfvsb/hidden2.d b/ld/testsuite/ld-elfvsb/hidden2.d
index 72a42d57bc..8fe2da65b9 100644
--- a/ld/testsuite/ld-elfvsb/hidden2.d
+++ b/ld/testsuite/ld-elfvsb/hidden2.d
@@ -5,5 +5,5 @@
Symbol table for image:
#...
-[ ]*[0-9]+ +[0-9]+: [0-9a-fA-F]* +0 +OBJECT +LOCAL +DEFAULT .* foo
+[ ]*[0-9]+: [0-9a-fA-F]* +0 +OBJECT +LOCAL +DEFAULT .* foo
#pass
diff --git a/ld/testsuite/ld-mips-elf/hash2.d b/ld/testsuite/ld-mips-elf/hash2.d
index 122edb80e1..a0fe4266f2 100644
--- a/ld/testsuite/ld-mips-elf/hash2.d
+++ b/ld/testsuite/ld-mips-elf/hash2.d
@@ -6,11 +6,11 @@
#...
+0x[0-9a-z]+ +\(MIPS_XHASH\) +0x[0-9a-z]+
#...
- +[0-9]+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +FUNC +GLOBAL +DEFAULT +([1-9]|PRC) _start
+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +FUNC +GLOBAL +DEFAULT +([1-9]|PRC) __start
#...
- +[0-9]+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +FUNC +GLOBAL +DEFAULT +([1-9]|PRC) main
+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +FUNC +GLOBAL +DEFAULT +([1-9]|PRC) _start
#...
- +[0-9]+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +FUNC +GLOBAL +DEFAULT +([1-9]|PRC) start
+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +FUNC +GLOBAL +DEFAULT +([1-9]|PRC) main
#...
- +[0-9]+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +FUNC +GLOBAL +DEFAULT +([1-9]|PRC) __start
+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +FUNC +GLOBAL +DEFAULT +([1-9]|PRC) start
#...
--
2.24.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 4/7] ld: Add a simple test for -z nosectionheader
2020-03-08 23:42 [PATCH 0/7] ELF: Don't require section header on ELF objects H.J. Lu
` (2 preceding siblings ...)
2020-03-08 23:42 ` [PATCH 3/7] readelf: Compute dynamic symbol table size from hash table H.J. Lu
@ 2020-03-08 23:42 ` H.J. Lu
2020-03-08 23:42 ` [PATCH 5/7] binutils: Add --remove-section-header tests H.J. Lu
` (3 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: H.J. Lu @ 2020-03-08 23:42 UTC (permalink / raw)
To: binutils; +Cc: Kaylee Blake
From: Kaylee Blake <klkblake@gmail.com>
2020-03-XX Kaylee Blake <klkblake@gmail.com>
PR ld/25617
* testsuite/ld-elf/nosectionheader.d: New file.
---
| 12 ++++++++++++
1 file changed, 12 insertions(+)
create mode 100644 ld/testsuite/ld-elf/nosectionheader.d
--git a/ld/testsuite/ld-elf/nosectionheader.d b/ld/testsuite/ld-elf/nosectionheader.d
new file mode 100644
index 0000000000..7154e095e1
--- /dev/null
+++ b/ld/testsuite/ld-elf/nosectionheader.d
@@ -0,0 +1,12 @@
+#source: start.s
+#ld: -z nosectionheader
+#readelf: -h -S
+
+#...
+ Start of section headers:[ \t]+0 \(bytes into file\)
+#...
+ Size of section headers:[ \t]+0 \(bytes\)
+ Number of section headers:[ \t]+0
+ Section header string table index:[ \t]+0
+
+There are no sections in this file.
--
2.24.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 5/7] binutils: Add --remove-section-header tests
2020-03-08 23:42 [PATCH 0/7] ELF: Don't require section header on ELF objects H.J. Lu
` (3 preceding siblings ...)
2020-03-08 23:42 ` [PATCH 4/7] ld: Add a simple test for -z nosectionheader H.J. Lu
@ 2020-03-08 23:42 ` H.J. Lu
2020-03-08 23:42 ` [PATCH 6/7] ld: Add tests for -z nosectionheader and --remove-section-header H.J. Lu
` (2 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: H.J. Lu @ 2020-03-08 23:42 UTC (permalink / raw)
To: binutils
Verify --remove-section-header with objcopy and strip is ignored for
relocatable file.
PR ld/25617
* testsuite/binutils-all/objcopy.exp: Verify
--remove-section-header ignored for relocatable file.
* testsuite/binutils-all/remove-header-1.d: New file.
---
binutils/testsuite/binutils-all/objcopy.exp | 13 +++++++++++++
| 8 ++++++++
2 files changed, 21 insertions(+)
create mode 100644 binutils/testsuite/binutils-all/remove-header-1.d
diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp
index 549b064e96..11bb8fea84 100644
--- a/binutils/testsuite/binutils-all/objcopy.exp
+++ b/binutils/testsuite/binutils-all/objcopy.exp
@@ -1115,6 +1115,13 @@ if [is_elf_format] {
run_dump_test "note-6-32"
}
run_dump_test "note-5"
+
+ set saved_OBJCOPYFLAGS $OBJCOPYFLAGS
+ append OBJCOPYFLAGS " --remove-section-header"
+
+ objcopy_test "simple copy with --remove-section-header" bintest.s
+
+ set OBJCOPYFLAGS $saved_OBJCOPYFLAGS
}
run_dump_test "copy-2"
@@ -1231,6 +1238,12 @@ if [is_elf_format] {
verbose [file rootname $t]
run_dump_test [file rootname $t]
}
+
+ # Test --remove-section-header
+ run_dump_test "remove-header-1" \
+ [list \
+ [list source strip-15${reloc_format}.s] \
+ [list as "${elf64} --defsym RELOC=${reloc}"]]
}
run_dump_test "localize-hidden-2"
--git a/binutils/testsuite/binutils-all/remove-header-1.d b/binutils/testsuite/binutils-all/remove-header-1.d
new file mode 100644
index 0000000000..60a9c407af
--- /dev/null
+++ b/binutils/testsuite/binutils-all/remove-header-1.d
@@ -0,0 +1,8 @@
+#PROG: strip
+#strip: -g --remove-section-header
+#readelf: -r
+
+Relocation section '\.rela?\.text' at offset .* contains 2 entries:
+ *Offset * Info * Type * Sym\. *Value * Sym\. *Name(?: * \+ * Addend)?
+0+00 * 0+0(?:1|b|32|103) * R_[^ ]* *(?: * 55aa)?
+#pass
--
2.24.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 6/7] ld: Add tests for -z nosectionheader and --remove-section-header
2020-03-08 23:42 [PATCH 0/7] ELF: Don't require section header on ELF objects H.J. Lu
` (4 preceding siblings ...)
2020-03-08 23:42 ` [PATCH 5/7] binutils: Add --remove-section-header tests H.J. Lu
@ 2020-03-08 23:42 ` H.J. Lu
2020-03-08 23:42 ` [PATCH 7/7] ld: Add -z nosectionheader test to bootstrap.exp H.J. Lu
2020-03-19 0:48 ` [PATCH 0/7] ELF: Don't require section header on ELF objects Fangrui Song
7 siblings, 0 replies; 18+ messages in thread
From: H.J. Lu @ 2020-03-08 23:42 UTC (permalink / raw)
To: binutils
Add tests to verify that the linker option, -z nosectionheader and
objcopy and strip option, --remove-section-header, work correctly
as well as linker can properly reconstruct dynamic symbol table from
PT_DYNAMIC segment.
PR ld/25617
* testsuite/ld-elf/no-section-header.exp: New file.
* testsuite/ld-elf/pr22393-2a-no-sec-hdr.nd: Likewise.
* testsuite/ld-elf/pr22393-2a-no-sec-hdr.rd: Likewise.
* testsuite/ld-elf/pr22393-2a-sec-hdr.rd: Likewise.
* testsuite/ld-elf/pr22393-2b-no-sec-hdr.nd: Likewise.
* testsuite/ld-elf/pr22393-2b-no-sec-hdr.rd: Likewise.
* testsuite/ld-elf/pr22393-2b-static-no-sec-hdr.rd: Likewise.
* testsuite/ld-elf/start-noheader.rd: Likewise.
* testsuite/ld-elf/start-shared-noheader-gnu.rd: Likewise.
* testsuite/ld-elf/start-shared-noheader-sysv.rd: Likewise.
* testsuite/ld-elf/start-shared-noheader.nd: Likewise.
---
| 336 ++++++++++++++++++
ld/testsuite/ld-elf/pr22393-2a-no-sec-hdr.nd | 3 +
ld/testsuite/ld-elf/pr22393-2a-no-sec-hdr.rd | 20 ++
ld/testsuite/ld-elf/pr22393-2a-sec-hdr.rd | 19 +
ld/testsuite/ld-elf/pr22393-2b-no-sec-hdr.nd | 3 +
ld/testsuite/ld-elf/pr22393-2b-no-sec-hdr.rd | 20 ++
.../ld-elf/pr22393-2b-static-no-sec-hdr.rd | 12 +
| 11 +
| 22 ++
| 22 ++
| 5 +
11 files changed, 473 insertions(+)
create mode 100644 ld/testsuite/ld-elf/no-section-header.exp
create mode 100644 ld/testsuite/ld-elf/pr22393-2a-no-sec-hdr.nd
create mode 100644 ld/testsuite/ld-elf/pr22393-2a-no-sec-hdr.rd
create mode 100644 ld/testsuite/ld-elf/pr22393-2a-sec-hdr.rd
create mode 100644 ld/testsuite/ld-elf/pr22393-2b-no-sec-hdr.nd
create mode 100644 ld/testsuite/ld-elf/pr22393-2b-no-sec-hdr.rd
create mode 100644 ld/testsuite/ld-elf/pr22393-2b-static-no-sec-hdr.rd
create mode 100644 ld/testsuite/ld-elf/start-noheader.rd
create mode 100644 ld/testsuite/ld-elf/start-shared-noheader-gnu.rd
create mode 100644 ld/testsuite/ld-elf/start-shared-noheader-sysv.rd
create mode 100644 ld/testsuite/ld-elf/start-shared-noheader.nd
--git a/ld/testsuite/ld-elf/no-section-header.exp b/ld/testsuite/ld-elf/no-section-header.exp
new file mode 100644
index 0000000000..97d36c8866
--- /dev/null
+++ b/ld/testsuite/ld-elf/no-section-header.exp
@@ -0,0 +1,336 @@
+# Expect script for --remove-section-header tests
+# Copyright (C) 2020 Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+# Written by H.J. Lu (hongjiu.lu@intel.com)
+#
+
+# Make sure that binutils can correctly handle ld output in ELF.
+
+if { ![istarget *-*-linux*] } {
+ return
+}
+
+proc binutils_test { prog_name ld_options test readelf_expected nm_expected} {
+ global as
+ global ld
+ global READELF
+ global NM
+ global objcopy
+ global strip
+ global srcdir
+ global subdir
+ global link_output
+
+ eval set prog \$$prog_name
+
+ set test_name "$prog_name --remove-section-header $ld_options ($test)"
+
+ if { ![ld_assemble $as $srcdir/$subdir/$test.s tmpdir/$test.o ] } {
+ unresolved "$test_name"
+ return
+ }
+
+ append ld_options " -z separate-code -z stack-size=0"
+ if { ![ld_link $ld tmpdir/$test "$ld_options tmpdir/$test.o"] } {
+ if { [string match "*not supported*" $link_output]
+ || [string match "*unrecognized option*" $link_output]
+ || [string match "*-z .* ignored*" $link_output] } {
+ unsupported "$ld_options is not supported by this target"
+ } else {
+ unresolved "$test_name"
+ }
+ return
+ }
+
+ send_log "$prog --remove-section-header tmpdir/$test\n"
+ set got [remote_exec host "$prog --remove-section-header tmpdir/$test"]
+ if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+ send_log "$got\n"
+ fail "$test_name"
+ return
+ }
+
+ send_log "$READELF -lSDs --wide tmpdir/$test > tmpdir/$test.out\n"
+ set got [remote_exec host "$READELF -lSDs --wide tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
+ if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+ send_log "$got\n"
+ unresolved "$test_name"
+ return
+ }
+
+ if { [regexp_diff "tmpdir/$test.out" "$srcdir/$subdir/$readelf_expected"] } then {
+ fail "$test_name"
+ return
+ }
+
+ if { [string match "*-shared *" $ld_options] } {
+ send_log "$NM -D tmpdir/$test > tmpdir/$test.out\n"
+ set got [remote_exec host "$NM -D tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
+ if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+ send_log "$got\n"
+ unresolved "$test_name"
+ return
+ }
+
+ if { [regexp_diff "tmpdir/$test.out" "$srcdir/$subdir/$nm_expected"] } then {
+ fail "$test_name"
+ return
+ }
+ }
+
+ pass "$test_name"
+}
+
+if { [istarget "mips*-*-*"] } {
+ set gnu_hash_style "sysv"
+} else {
+ set gnu_hash_style "gnu"
+}
+
+binutils_test objcopy "--hash-style=both" start start-noheader.rd \
+ start-noheader.nd
+binutils_test objcopy "--hash-style=gnu" start start-noheader.rd \
+ start-noheader.nd
+binutils_test objcopy "--hash-style=sysv" start start-noheader.rd \
+ start-noheader.nd
+binutils_test objcopy "--hash-style=both -shared" start \
+ start-shared-noheader-$gnu_hash_style.rd start-shared-noheader.nd
+binutils_test objcopy "--hash-style=gnu -shared" start \
+ start-shared-noheader-$gnu_hash_style.rd start-shared-noheader.nd
+binutils_test objcopy "--hash-style=sysv -shared" start \
+ start-shared-noheader-sysv.rd start-shared-noheader.nd
+binutils_test strip "--hash-style=both" start start-noheader.rd \
+ start-noheader.nd
+binutils_test strip "--hash-style=gnu" start start-noheader.rd \
+ start-noheader.nd
+binutils_test strip "--hash-style=sysv" start start-noheader.rd \
+ start-noheader.nd
+binutils_test strip "--hash-style=both -shared" start \
+ start-shared-noheader-$gnu_hash_style.rd start-shared-noheader.nd
+binutils_test strip "--hash-style=gnu -shared" start \
+ start-shared-noheader-$gnu_hash_style.rd start-shared-noheader.nd
+binutils_test strip "--hash-style=sysv -shared" start \
+ start-shared-noheader-sysv.rd start-shared-noheader.nd
+
+# Skip non-native targets or -shared is not supported.
+if { ![isnative] || ![check_shared_lib_support] } {
+ return
+}
+
+proc binutils_run_test { prog } {
+ global READELF
+ global NM
+ global objcopy
+ global strip
+ global srcdir
+ global subdir
+ # Add $NOPIE_CFLAGS and $NOPIE_LDFLAGS if non-PIE is required.
+ global NOPIE_CFLAGS NOPIE_LDFLAGS
+
+ if { "$prog" == "" } {
+ set prog_name none
+ set ld_options "-Wl,-z,nosectionheader"
+ set sec_hdr "no-sec-hdr"
+ } else {
+ set prog_name $prog
+ set ld_options ""
+ set sec_hdr "sec-hdr"
+ switch -- $prog {
+ objcopy
+ { set prog $objcopy }
+ strip
+ { set prog $strip }
+ default
+ {
+ fail "Build pr22393-2a-no-sec-hdr.so ($prog_name)"
+ break
+ }
+ }
+ }
+
+ run_cc_link_tests [list \
+ [list \
+ "Build pr22393-2a-no-sec-hdr.so ($prog_name)" \
+ "-shared -Wl,-z,separate-code,--hash-style=sysv \
+ $ld_options" \
+ "-fPIC" \
+ {pr22393-2a.c} \
+ [list \
+ [list "readelf" "-lWSDs" "pr22393-2a-$sec_hdr.rd"] \
+ [list "nm" "-Ds" "pr22393-2a-no-sec-hdr.nd"] \
+ ]\
+ "pr22393-2a-no-sec-hdr.so" \
+ ] \
+ [list \
+ "Build pr22393-2a-now-no-sec-hdr.so ($prog_name)" \
+ "-shared -Wl,-z,separate-code,-z,now,--hash-style=gnu \
+ $ld_options" \
+ "-fPIC" \
+ {pr22393-2a.c} \
+ [list \
+ [list "readelf" "-lWSDs" "pr22393-2a-$sec_hdr.rd"] \
+ [list "nm" "-Ds" "pr22393-2a-no-sec-hdr.nd"] \
+ ]\
+ "pr22393-2a-now-no-sec-hdr.so" \
+ ] \
+ ]
+
+ if { "$prog_name" != "none" } {
+ send_log "$prog --remove-section-header tmpdir/pr22393-2a-no-sec-hdr.so\n"
+ set got [remote_exec host "$prog --remove-section-header tmpdir/pr22393-2a-no-sec-hdr.so"]
+ if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+ send_log "$got\n"
+ fail "Build pr22393-2a-no-sec-hdr.so ($prog_name)"
+ return
+ }
+
+ send_log "$READELF -lWSDs tmpdir/pr22393-2a-no-sec-hdr.so > tmpdir/dump.out\n"
+ set got [remote_exec host "$READELF -lWSDs tmpdir/pr22393-2a-no-sec-hdr.so" "" "/dev/null" "tmpdir/dump.out"]
+ if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+ send_log "$got\n"
+ unresolved "Build pr22393-2a-no-sec-hdr.so ($prog_name)"
+ return
+ }
+
+ if { [regexp_diff "tmpdir/dump.out" "$srcdir/$subdir/pr22393-2a-no-sec-hdr.rd"] } then {
+ unresolved "Build pr22393-2a-no-sec-hdr.so ($prog_name)"
+ return
+ }
+
+ send_log "$NM -Ds tmpdir/pr22393-2a-no-sec-hdr.so > tmpdir/dump.out\n"
+ set got [remote_exec host "$NM -Ds tmpdir/pr22393-2a-no-sec-hdr.so" "" "/dev/null" "tmpdir/dump.out"]
+ if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+ send_log "$got\n"
+ unresolved "Build pr22393-2a-no-sec-hdr.so ($prog_name)"
+ return
+ }
+
+ if { [regexp_diff "tmpdir/dump.out" "$srcdir/$subdir/pr22393-2a-no-sec-hdr.nd"] } then {
+ unresolved "Build pr22393-2a-no-sec-hdr.so ($prog_name)"
+ return
+ }
+
+ send_log "$prog --remove-section-header tmpdir/pr22393-2a-now-no-sec-hdr.so\n"
+ set got [remote_exec host "$prog --remove-section-header tmpdir/pr22393-2a-now-no-sec-hdr.so"]
+ if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+ send_log "$got\n"
+ fail "Build pr22393-2a-now-no-sec-hdr.so ($prog_name)"
+ return
+ }
+
+ send_log "$READELF -lWSDs tmpdir/pr22393-2a-now-no-sec-hdr.so > tmpdir/dump.out\n"
+ set got [remote_exec host "$READELF -lWSDs tmpdir/pr22393-2a-now-no-sec-hdr.so" "" "/dev/null" "tmpdir/dump.out"]
+ if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+ send_log "$got\n"
+ unresolved "Build pr22393-2a-now-no-sec-hdr.so ($prog_name)"
+ return
+ }
+
+ if { [regexp_diff "tmpdir/dump.out" "$srcdir/$subdir/pr22393-2a-no-sec-hdr.rd"] } then {
+ unresolved "Build pr22393-2a-now-no-sec-hdr.so ($prog_name)"
+ return
+ }
+
+ send_log "$NM -Ds tmpdir/pr22393-2a-now-no-sec-hdr.so > tmpdir/dump.out\n"
+ set got [remote_exec host "$NM -Ds tmpdir/pr22393-2a-now-no-sec-hdr.so" "" "/dev/null" "tmpdir/dump.out"]
+ if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+ send_log "$got\n"
+ unresolved "Build pr22393-2a-no-sec-hdr.so ($prog_name)"
+ return
+ }
+
+ if { [regexp_diff "tmpdir/dump.out" "$srcdir/$subdir/pr22393-2a-no-sec-hdr.nd"] } then {
+ unresolved "Build pr22393-2a-no-sec-hdr.so ($prog_name)"
+ return
+ }
+ }
+
+ run_cc_link_tests [list \
+ [list \
+ "Build pr22393-2 (-z nosectionheader, $prog_name)" \
+ "$NOPIE_LDFLAGS -Wl,-z,separate-code,--no-as-needed \
+ -Wl,--hash-style=sysv -Wl,-z,nosectionheader \
+ tmpdir/pr22393-2a-no-sec-hdr.so" \
+ "$NOPIE_CFLAGS" \
+ {pr22393-2b.c} \
+ {{readelf -lWSDs pr22393-2b-no-sec-hdr.rd} \
+ {nm -Ds pr22393-2b-no-sec-hdr.nd}} \
+ "pr22393-2-no-sec-hdr" \
+ ] \
+ [list \
+ "Build pr22393-2 (PIE, -z nosectionheader, $prog_name)" \
+ "-pie -Wl,-z,separate-code,--no-as-needed,--hash-style=gnu \
+ -Wl,-z,nosectionheader tmpdir/pr22393-2a-now-no-sec-hdr.so" \
+ "-fPIE" \
+ {pr22393-2b.c} \
+ {{readelf -lWSDs pr22393-2b-no-sec-hdr.rd} \
+ {nm -Ds pr22393-2b-no-sec-hdr.nd}} \
+ "pr22393-2-pie-no-sec-hdr" \
+ ] \
+ [list \
+ "Build pr22393-2 (static, -z nosectionheader, $prog_name)" \
+ "-static -Wl,-z,separate-code -Wl,-z,nosectionheader" \
+ "" \
+ {pr22393-2a.c pr22393-2b.c} \
+ {{readelf -lSWDs pr22393-2b-static-no-sec-hdr.rd}} \
+ "pr22393-2-static-no-sec-hdr" \
+ ] \
+ ]
+
+ run_ld_link_exec_tests [list \
+ [list \
+ "Run pr22393-2 (-z nosectionheader, $prog_name)" \
+ "$NOPIE_LDFLAGS -Wl,-z,separate-code,--no-as-needed \
+ -Wl,--hash-style=sysv -Wl,-z,nosectionheader \
+ tmpdir/pr22393-2a-no-sec-hdr.so" \
+ "" \
+ {pr22393-2b.c} \
+ "pr22393-2-no-sec-hdr" \
+ "pass.out" \
+ "$NOPIE_CFLAGS" \
+ ] \
+ [list \
+ "Run pr22393-2 (PIE, -z nosectionheader, $prog_name)" \
+ "-pie -Wl,-z,separate-code,--no-as-needed,--hash-style=gnu \
+ -Wl,-z,nosectionheader tmpdir/pr22393-2a-now-no-sec-hdr.so" \
+ "" \
+ {pr22393-2b.c} \
+ "pr22393-2-pie-no-sec-hdr" \
+ "pass.out" \
+ "-fPIE" \
+ ] \
+ [list \
+ "Run pr22393-2 (static, -z nosectionheader, $prog_name)" \
+ "-static -Wl,-z,separate-code -Wl,-z,nosectionheader" \
+ "" \
+ {pr22393-2a.c pr22393-2b.c} \
+ "pr22393-2-static-no-sec-hdr" \
+ "pass.out" \
+ ] \
+ ]
+}
+
+if { [istarget *-*-linux*]
+ || [istarget *-*-nacl*]
+ || [istarget *-*-gnu*] } {
+ binutils_run_test ""
+ binutils_run_test objcopy
+ binutils_run_test strip
+}
diff --git a/ld/testsuite/ld-elf/pr22393-2a-no-sec-hdr.nd b/ld/testsuite/ld-elf/pr22393-2a-no-sec-hdr.nd
new file mode 100644
index 0000000000..86fcc624af
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr22393-2a-no-sec-hdr.nd
@@ -0,0 +1,3 @@
+#...
+ + U _?puts
+[0-9a-z]+ T _?test
diff --git a/ld/testsuite/ld-elf/pr22393-2a-no-sec-hdr.rd b/ld/testsuite/ld-elf/pr22393-2a-no-sec-hdr.rd
new file mode 100644
index 0000000000..65fffba478
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr22393-2a-no-sec-hdr.rd
@@ -0,0 +1,20 @@
+#readelf: -lWSDs
+
+There are no sections in this file.
+
+#...
+Program Headers:
+ Type +Offset +VirtAddr.*
+# On MIPS, the first segment is for .reginfo.
+#...
+ LOAD .*
+#...
+ DYNAMIC .*
+#...
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND +
+#...
+ +[0-9]+: +[a-f0-9]+ +0 +FUNC +GLOBAL +DEFAULT +UND +_?puts
+#...
+ +[0-9]+: +[a-f0-9]+ +[0-9]+ +FUNC +GLOBAL +DEFAULT +[0-9]+ +_?test
+#pass
diff --git a/ld/testsuite/ld-elf/pr22393-2a-sec-hdr.rd b/ld/testsuite/ld-elf/pr22393-2a-sec-hdr.rd
new file mode 100644
index 0000000000..b244c8b1a5
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr22393-2a-sec-hdr.rd
@@ -0,0 +1,19 @@
+#readelf: -lWSDs
+
+There are [0-9]+ section headers, starting at offset 0x[a-f0-9]+:
+#...
+Program Headers:
+ Type +Offset +VirtAddr.*
+# On MIPS, the first segment is for .reginfo.
+#...
+ LOAD .*
+#...
+ DYNAMIC .*
+#...
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND +
+#...
+ +[0-9]+: +[a-f0-9]+ +0 +FUNC +GLOBAL +DEFAULT +UND +_?puts
+#...
+ +[0-9]+: +[a-f0-9]+ +[0-9]+ +FUNC +GLOBAL +DEFAULT +[0-9]+ +_?test
+#pass
diff --git a/ld/testsuite/ld-elf/pr22393-2b-no-sec-hdr.nd b/ld/testsuite/ld-elf/pr22393-2b-no-sec-hdr.nd
new file mode 100644
index 0000000000..0518488872
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr22393-2b-no-sec-hdr.nd
@@ -0,0 +1,3 @@
+#...
+ + U __libc_start_main
+ + U _?test
diff --git a/ld/testsuite/ld-elf/pr22393-2b-no-sec-hdr.rd b/ld/testsuite/ld-elf/pr22393-2b-no-sec-hdr.rd
new file mode 100644
index 0000000000..5287139af7
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr22393-2b-no-sec-hdr.rd
@@ -0,0 +1,20 @@
+#readelf: -lWSDs
+
+There are no sections in this file.
+
+#...
+Program Headers:
+ Type +Offset +VirtAddr.*
+# On MIPS, the first segment is for .reginfo.
+#...
+ LOAD .*
+#...
+ DYNAMIC .*
+#...
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND +
+#...
+ +[0-9]+: +[a-f0-9]+ +0 +FUNC +GLOBAL +DEFAULT +UND +__libc_start_main
+#...
+ +[0-9]+: +[a-f0-9]+ +0+ +FUNC +GLOBAL +DEFAULT +UND +_?test
+#pass
diff --git a/ld/testsuite/ld-elf/pr22393-2b-static-no-sec-hdr.rd b/ld/testsuite/ld-elf/pr22393-2b-static-no-sec-hdr.rd
new file mode 100644
index 0000000000..92b1dc9ead
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr22393-2b-static-no-sec-hdr.rd
@@ -0,0 +1,12 @@
+#readelf: -lWSDs
+
+There are no sections in this file.
+
+#...
+Program Headers:
+ Type +Offset +VirtAddr.*
+# On MIPS, the first segment is for .reginfo.
+#...
+ LOAD .*
+#...
+Dynamic symbol information is not available for displaying symbols\.
--git a/ld/testsuite/ld-elf/start-noheader.rd b/ld/testsuite/ld-elf/start-noheader.rd
new file mode 100644
index 0000000000..2479e34087
--- /dev/null
+++ b/ld/testsuite/ld-elf/start-noheader.rd
@@ -0,0 +1,11 @@
+#readelf: -SlDs --wide
+
+There are no sections in this file.
+
+#...
+Program Headers:
+ Type +Offset +VirtAddr.*
+# On MIPS, the first segment is for .reginfo.
+#...
+ LOAD .*
+#pass
--git a/ld/testsuite/ld-elf/start-shared-noheader-gnu.rd b/ld/testsuite/ld-elf/start-shared-noheader-gnu.rd
new file mode 100644
index 0000000000..3397a576ba
--- /dev/null
+++ b/ld/testsuite/ld-elf/start-shared-noheader-gnu.rd
@@ -0,0 +1,22 @@
+#readelf: -SlDs --wide
+
+There are no sections in this file.
+
+#...
+Program Headers:
+ Type +Offset +VirtAddr.*
+# On MIPS, the first segment is for .reginfo.
+#...
+ LOAD .*
+#...
+ DYNAMIC .*
+#...
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND +
+#...
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +_start
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +main
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +start
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +_main
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +__start
+#pass
--git a/ld/testsuite/ld-elf/start-shared-noheader-sysv.rd b/ld/testsuite/ld-elf/start-shared-noheader-sysv.rd
new file mode 100644
index 0000000000..23a87f98bc
--- /dev/null
+++ b/ld/testsuite/ld-elf/start-shared-noheader-sysv.rd
@@ -0,0 +1,22 @@
+#readelf: -SlDs --wide
+
+There are no sections in this file.
+
+#...
+Program Headers:
+ Type +Offset +VirtAddr.*
+# On MIPS, the first segment is for .reginfo.
+#...
+ LOAD .*
+#...
+ DYNAMIC .*
+#...
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND +
+#...
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +__start
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +_start
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +main
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +start
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +[0-9]+ +_main
+#pass
--git a/ld/testsuite/ld-elf/start-shared-noheader.nd b/ld/testsuite/ld-elf/start-shared-noheader.nd
new file mode 100644
index 0000000000..2d3ba70e53
--- /dev/null
+++ b/ld/testsuite/ld-elf/start-shared-noheader.nd
@@ -0,0 +1,5 @@
+[0-9a-z]+ A __start
+[0-9a-z]+ A _main
+[0-9a-z]+ A _start
+[0-9a-z]+ A main
+[0-9a-z]+ A start
--
2.24.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 7/7] ld: Add -z nosectionheader test to bootstrap.exp
2020-03-08 23:42 [PATCH 0/7] ELF: Don't require section header on ELF objects H.J. Lu
` (5 preceding siblings ...)
2020-03-08 23:42 ` [PATCH 6/7] ld: Add tests for -z nosectionheader and --remove-section-header H.J. Lu
@ 2020-03-08 23:42 ` H.J. Lu
2020-03-19 0:48 ` [PATCH 0/7] ELF: Don't require section header on ELF objects Fangrui Song
7 siblings, 0 replies; 18+ messages in thread
From: H.J. Lu @ 2020-03-08 23:42 UTC (permalink / raw)
To: binutils
PR ld/25617
* testsuite/ld-bootstrap/bootstrap.exp: Add -z nosectionheader
test.
---
ld/testsuite/ld-bootstrap/bootstrap.exp | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/ld/testsuite/ld-bootstrap/bootstrap.exp b/ld/testsuite/ld-bootstrap/bootstrap.exp
index ba51e50a02..5d74caf2d6 100644
--- a/ld/testsuite/ld-bootstrap/bootstrap.exp
+++ b/ld/testsuite/ld-bootstrap/bootstrap.exp
@@ -55,6 +55,9 @@ set test_flags {"" "strip" "--static" "-Wl,--traditional-format"
if { [istarget "powerpc-*-*"] } {
lappend test_flags "-Wl,--ppc476-workaround"
}
+if { [is_elf_format] && ![is_bad_symtab] } {
+ lappend test_flags "-Wl,-z,nosectionheader"
+}
set gcc_B_opt_save $gcc_B_opt
@@ -80,9 +83,12 @@ foreach flags $test_flags {
set testname "bootstrap"
}}
- # --static is meaningless and --relax is incompatible with -r.
+ # --static is meaningless. --relax and -z nosectionheader are
+ # incompatible with -r.
regsub -- "-Wl," $flags "" partial_flags
- if { "$partial_flags" == "--static" || "$partial_flags" == "--relax" } {
+ if { "$partial_flags" == "--static" \
+ || "$partial_flags" == "--relax" \
+ || [string match "*nosectionheader*" "$partial_flags"] } {
set partial_flags ""
}
--
2.24.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 0/7] ELF: Don't require section header on ELF objects
2020-03-08 23:42 [PATCH 0/7] ELF: Don't require section header on ELF objects H.J. Lu
` (6 preceding siblings ...)
2020-03-08 23:42 ` [PATCH 7/7] ld: Add -z nosectionheader test to bootstrap.exp H.J. Lu
@ 2020-03-19 0:48 ` Fangrui Song
2020-03-19 1:32 ` H.J. Lu
7 siblings, 1 reply; 18+ messages in thread
From: Fangrui Song @ 2020-03-19 0:48 UTC (permalink / raw)
To: hjl.tools; +Cc: binutils
>Section header isn't mandatory on ELF executable nor shared library.
>This patch set adds a new linker option, -z nosectionheader, to omit
>ELF section header when building an executable or shared library, an
>objcopy and strip option, --remove-section-header, to remove ELF
>section header from an executable or shared library.
>
>The PT_DYNAMIC segment contains DT_HASH/DT_GNU_HASH/DT_MIPS_XHASH,
>DT_STRTAB, DT_SYMTAB, DT_STRSZ and DT_SYMENT entries, which can be
>used to reconstruct dynamic symbol table when section header isn't
>available. For DT_HASH, the number of dynamic symbol table entries
>equals the number of chains. For DT_GNU_HASH/DT_MIPS_XHASH, only
>defined symbols with non-STB_LOCAL indings are in hash table. Since
>in dynamic symbol table, all symbols with STB_LOCAL binding are placed
>before symbols with other bindings and all undefined symbols are placed
>before defined ones, the highest symbol index in DT_GNU_HASH and
>DT_MIPS_XHASH is the highest dynamic symbol table index.
>
>
>H.J. Lu (5):
> bfd: Reconstruct dynamic symbol table from PT_DYNAMIC segment
> readelf: Compute dynamic symbol table size from hash table
> binutils: Add --remove-section-header tests
> ld: Add tests for -z nosectionheader and --remove-section-header
> ld: Add -z nosectionheader test to bootstrap.exp
>
>Kaylee Blake (2):
> ELF: Don't require section header on ELF objects
> ld: Add a simple test for -z nosectionheader
>
> bfd/bfd-in2.h | 8 +-
> bfd/bfd.c | 8 +-
> bfd/elf-bfd.h | 8 +
> bfd/elf.c | 443 ++++++++++++++++++
> bfd/elfcode.h | 174 ++++++-
> bfd/elflink.c | 148 ++++--
> bfd/elfxx-target.h | 6 +-
> binutils/NEWS | 3 +
> binutils/doc/binutils.texi | 12 +
> binutils/objcopy.c | 54 ++-
> binutils/readelf.c | 226 ++++-----
> binutils/testsuite/binutils-all/objcopy.exp | 13 +
> .../testsuite/binutils-all/remove-header-1.d | 8 +
> ld/NEWS | 3 +
> ld/emultempl/elf.em | 4 +
> ld/ld.h | 3 +
> ld/ld.texi | 6 +
> ld/ldlang.c | 4 +
> ld/lexsup.c | 12 +
> ld/testsuite/ld-bootstrap/bootstrap.exp | 10 +-
> ld/testsuite/ld-elf/hash.d | 8 +-
> ld/testsuite/ld-elf/no-section-header.exp | 336 +++++++++++++
> ld/testsuite/ld-elf/nosectionheader.d | 12 +
> ld/testsuite/ld-elf/pr13195.d | 2 +-
> ld/testsuite/ld-elf/pr22393-2a-no-sec-hdr.nd | 3 +
> ld/testsuite/ld-elf/pr22393-2a-no-sec-hdr.rd | 20 +
> ld/testsuite/ld-elf/pr22393-2a-sec-hdr.rd | 19 +
> ld/testsuite/ld-elf/pr22393-2b-no-sec-hdr.nd | 3 +
> ld/testsuite/ld-elf/pr22393-2b-no-sec-hdr.rd | 20 +
> .../ld-elf/pr22393-2b-static-no-sec-hdr.rd | 12 +
> ld/testsuite/ld-elf/start-noheader.rd | 11 +
> .../ld-elf/start-shared-noheader-gnu.rd | 22 +
> .../ld-elf/start-shared-noheader-sysv.rd | 22 +
> ld/testsuite/ld-elf/start-shared-noheader.nd | 5 +
> ld/testsuite/ld-elfvsb/hidden2.d | 2 +-
> ld/testsuite/ld-mips-elf/hash2.d | 8 +-
> 36 files changed, 1458 insertions(+), 200 deletions(-)
> create mode 100644 binutils/testsuite/binutils-all/remove-header-1.d
> create mode 100644 ld/testsuite/ld-elf/no-section-header.exp
> create mode 100644 ld/testsuite/ld-elf/nosectionheader.d
> create mode 100644 ld/testsuite/ld-elf/pr22393-2a-no-sec-hdr.nd
> create mode 100644 ld/testsuite/ld-elf/pr22393-2a-no-sec-hdr.rd
> create mode 100644 ld/testsuite/ld-elf/pr22393-2a-sec-hdr.rd
> create mode 100644 ld/testsuite/ld-elf/pr22393-2b-no-sec-hdr.nd
> create mode 100644 ld/testsuite/ld-elf/pr22393-2b-no-sec-hdr.rd
> create mode 100644 ld/testsuite/ld-elf/pr22393-2b-static-no-sec-hdr.rd
> create mode 100644 ld/testsuite/ld-elf/start-noheader.rd
> create mode 100644 ld/testsuite/ld-elf/start-shared-noheader-gnu.rd
> create mode 100644 ld/testsuite/ld-elf/start-shared-noheader-sysv.rd
> create mode 100644 ld/testsuite/ld-elf/start-shared-noheader.nd
>
>--
>2.24.1
For objcopy --remove-section-header, we can probably implement an
enhanced feature --strip-sections first. eu-strip and llvm-objcopy
(since https://reviews.llvm.org/D38335) have --strip-sections.
--strip-sections strips the section header table and sections not
covered by a segment. In llvm-objcopy, a non-SHF_ALLOC section can
covered by a segment.
For -z nosectionheader, I am questioning about the potential use case.
As others have commented on the thread "ELF: Don't require section header on ELF objects",
such shared objects should not be used for link. For runtime only use
cases, perhaps we can do that with a post-processing tool.
For readelf dumping of PT_DYNAMIC and DT_GNU_HASH, I think they are useful features.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 0/7] ELF: Don't require section header on ELF objects
2020-03-19 0:48 ` [PATCH 0/7] ELF: Don't require section header on ELF objects Fangrui Song
@ 2020-03-19 1:32 ` H.J. Lu
2020-03-19 1:45 ` Kaylee Blake
0 siblings, 1 reply; 18+ messages in thread
From: H.J. Lu @ 2020-03-19 1:32 UTC (permalink / raw)
To: Fangrui Song, Kaylee Blake; +Cc: Binutils
On Wed, Mar 18, 2020 at 5:48 PM Fangrui Song <i@maskray.me> wrote:
>
> >Section header isn't mandatory on ELF executable nor shared library.
> >This patch set adds a new linker option, -z nosectionheader, to omit
> >ELF section header when building an executable or shared library, an
> >objcopy and strip option, --remove-section-header, to remove ELF
> >section header from an executable or shared library.
> >
> >The PT_DYNAMIC segment contains DT_HASH/DT_GNU_HASH/DT_MIPS_XHASH,
> >DT_STRTAB, DT_SYMTAB, DT_STRSZ and DT_SYMENT entries, which can be
> >used to reconstruct dynamic symbol table when section header isn't
> >available. For DT_HASH, the number of dynamic symbol table entries
> >equals the number of chains. For DT_GNU_HASH/DT_MIPS_XHASH, only
> >defined symbols with non-STB_LOCAL indings are in hash table. Since
> >in dynamic symbol table, all symbols with STB_LOCAL binding are placed
> >before symbols with other bindings and all undefined symbols are placed
> >before defined ones, the highest symbol index in DT_GNU_HASH and
> >DT_MIPS_XHASH is the highest dynamic symbol table index.
> >
> >
> >H.J. Lu (5):
> > bfd: Reconstruct dynamic symbol table from PT_DYNAMIC segment
> > readelf: Compute dynamic symbol table size from hash table
> > binutils: Add --remove-section-header tests
> > ld: Add tests for -z nosectionheader and --remove-section-header
> > ld: Add -z nosectionheader test to bootstrap.exp
> >
> >Kaylee Blake (2):
> > ELF: Don't require section header on ELF objects
> > ld: Add a simple test for -z nosectionheader
> For objcopy --remove-section-header, we can probably implement an
> enhanced feature --strip-sections first. eu-strip and llvm-objcopy
> (since https://reviews.llvm.org/D38335) have --strip-sections.
I have renamed --remove-section-header to --strip-sections on
users/hjl/pr25617/master branch:
https://gitlab.com/x86-binutils/binutils-gdb/-/tree/users/hjl/pr25617/master
Kaylee, is your paper work with FSF in order? I will submit the updated
patch set after your paper is on file with FSF.
> --strip-sections strips the section header table and sections not
> covered by a segment. In llvm-objcopy, a non-SHF_ALLOC section can
> covered by a segment.
I think objcopy does it by default.
>
> For -z nosectionheader, I am questioning about the potential use case.
> As others have commented on the thread "ELF: Don't require section header on ELF objects",
> such shared objects should not be used for link. For runtime only use
> cases, perhaps we can do that with a post-processing tool.
-z nosectionheader works on both executable and shared library. The
use case for shared library can be dlopen-only shared library.
>
> For readelf dumping of PT_DYNAMIC and DT_GNU_HASH, I think they are useful features.
I submitted a separate readelf patch:
https://sourceware.org/pipermail/binutils/2020-March/110211.html
Thanks.
--
H.J.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 0/7] ELF: Don't require section header on ELF objects
2020-03-19 1:32 ` H.J. Lu
@ 2020-03-19 1:45 ` Kaylee Blake
2020-05-02 14:19 ` H.J. Lu
0 siblings, 1 reply; 18+ messages in thread
From: Kaylee Blake @ 2020-03-19 1:45 UTC (permalink / raw)
To: Binutils
On 19/3/20 12:02 pm, H.J. Lu wrote:
> Kaylee, is your paper work with FSF in order? I will submit the updated
> patch set after your paper is on file with FSF.
I'm waiting on a response from them at the moment.
--
Kaylee Blake <klkblake@gmail.com>
C is the worst language, except for all the others.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 0/7] ELF: Don't require section header on ELF objects
2020-03-19 1:45 ` Kaylee Blake
@ 2020-05-02 14:19 ` H.J. Lu
[not found] ` <06c41571-09ef-d107-ee21-38af17f6d20b@gmail.com>
0 siblings, 1 reply; 18+ messages in thread
From: H.J. Lu @ 2020-05-02 14:19 UTC (permalink / raw)
To: Kaylee Blake; +Cc: Binutils
On Wed, Mar 18, 2020 at 6:46 PM Kaylee Blake via Binutils
<binutils@sourceware.org> wrote:
>
> On 19/3/20 12:02 pm, H.J. Lu wrote:
> > Kaylee, is your paper work with FSF in order? I will submit the updated
> > patch set after your paper is on file with FSF.
>
> I'm waiting on a response from them at the moment.
>
Hi Kaylee,
Any update on your paper work with FSF?
--
H.J.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Has FSF stopped processing copyright paperwork?
[not found] ` <06c41571-09ef-d107-ee21-38af17f6d20b@gmail.com>
@ 2020-08-07 13:11 ` H.J. Lu
2020-08-07 13:28 ` Richard Biener
2020-08-14 15:25 ` Kaylee Blake
0 siblings, 2 replies; 18+ messages in thread
From: H.J. Lu @ 2020-08-07 13:11 UTC (permalink / raw)
To: Kaylee Blake, Binutils, GCC Development, GNU C Library
On Tue, May 5, 2020 at 6:42 PM Kaylee Blake <klkblake@gmail.com> wrote:
>
> On 2/5/20 11:49 pm, H.J. Lu wrote:
> > On Wed, Mar 18, 2020 at 6:46 PM Kaylee Blake via Binutils
> > <binutils@sourceware.org> wrote:
> >>
> >> On 19/3/20 12:02 pm, H.J. Lu wrote:
> >>> Kaylee, is your paper work with FSF in order? I will submit the updated
> >>> patch set after your paper is on file with FSF.
> >>
> >> I'm waiting on a response from them at the moment.
> >>
> >
> > Hi Kaylee,
> >
> > Any update on your paper work with FSF?
> >
>
> Still waiting; apparently their work process has been dramatically
> slowed by the whole COVID-19 situation.
>
> --
> Kaylee Blake <klkblake@gmail.com>
> C is the worst language, except for all the others.
Hi,
I submitted a set of binutils patches:
https://sourceware.org/pipermail/binutils/2020-March/000013.html
including contribution from Kaylee Blake <klkblake@gmail.com>.
Can someone check if Kaylee's paperwork is on file with FSF?
Thanks.
--
H.J.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Has FSF stopped processing copyright paperwork?
2020-08-07 13:11 ` Has FSF stopped processing copyright paperwork? H.J. Lu
@ 2020-08-07 13:28 ` Richard Biener
2020-08-14 15:25 ` Kaylee Blake
1 sibling, 0 replies; 18+ messages in thread
From: Richard Biener @ 2020-08-07 13:28 UTC (permalink / raw)
To: H.J. Lu; +Cc: Kaylee Blake, Binutils, GCC Development, GNU C Library
On Fri, Aug 7, 2020 at 3:14 PM H.J. Lu via Gcc <gcc@gcc.gnu.org> wrote:
>
> On Tue, May 5, 2020 at 6:42 PM Kaylee Blake <klkblake@gmail.com> wrote:
> >
> > On 2/5/20 11:49 pm, H.J. Lu wrote:
> > > On Wed, Mar 18, 2020 at 6:46 PM Kaylee Blake via Binutils
> > > <binutils@sourceware.org> wrote:
> > >>
> > >> On 19/3/20 12:02 pm, H.J. Lu wrote:
> > >>> Kaylee, is your paper work with FSF in order? I will submit the updated
> > >>> patch set after your paper is on file with FSF.
> > >>
> > >> I'm waiting on a response from them at the moment.
> > >>
> > >
> > > Hi Kaylee,
> > >
> > > Any update on your paper work with FSF?
> > >
> >
> > Still waiting; apparently their work process has been dramatically
> > slowed by the whole COVID-19 situation.
> >
> > --
> > Kaylee Blake <klkblake@gmail.com>
> > C is the worst language, except for all the others.
>
> Hi,
>
> I submitted a set of binutils patches:
>
> https://sourceware.org/pipermail/binutils/2020-March/000013.html
>
> including contribution from Kaylee Blake <klkblake@gmail.com>.
> Can someone check if Kaylee's paperwork is on file with FSF?
Don't see her in the list.
Richard.
> Thanks.
>
> --
> H.J.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Has FSF stopped processing copyright paperwork?
2020-08-07 13:11 ` Has FSF stopped processing copyright paperwork? H.J. Lu
2020-08-07 13:28 ` Richard Biener
@ 2020-08-14 15:25 ` Kaylee Blake
2021-04-02 13:45 ` H.J. Lu
1 sibling, 1 reply; 18+ messages in thread
From: Kaylee Blake @ 2020-08-14 15:25 UTC (permalink / raw)
To: H.J. Lu, Binutils, GCC Development, GNU C Library
On 7/8/20 10:41 pm, H.J. Lu wrote:
> On Tue, May 5, 2020 at 6:42 PM Kaylee Blake <klkblake@gmail.com> wrote:
>>
>> On 2/5/20 11:49 pm, H.J. Lu wrote:
>>> On Wed, Mar 18, 2020 at 6:46 PM Kaylee Blake via Binutils
>>> <binutils@sourceware.org> wrote:
>>>>
>>>> On 19/3/20 12:02 pm, H.J. Lu wrote:
>>>>> Kaylee, is your paper work with FSF in order? I will submit the updated
>>>>> patch set after your paper is on file with FSF.
>>>>
>>>> I'm waiting on a response from them at the moment.
>>>>
>>>
>>> Hi Kaylee,
>>>
>>> Any update on your paper work with FSF?
>>>
>>
>> Still waiting; apparently their work process has been dramatically
>> slowed by the whole COVID-19 situation.
>>
>> --
>> Kaylee Blake <klkblake@gmail.com>
>> C is the worst language, except for all the others.
>
> Hi,
>
> I submitted a set of binutils patches:
>
> https://sourceware.org/pipermail/binutils/2020-March/000013.html
>
> including contribution from Kaylee Blake <klkblake@gmail.com>.
> Can someone check if Kaylee's paperwork is on file with FSF?
>
> Thanks.
>
I needed clarification on some of the language in the contract, and with
them being so busy that has been taking a while. They've confirmed it's
still in their work queue.
--
Kaylee Blake <klkblake@gmail.com>
C is the worst language, except for all the others.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Has FSF stopped processing copyright paperwork?
2020-08-14 15:25 ` Kaylee Blake
@ 2021-04-02 13:45 ` H.J. Lu
2021-04-02 15:21 ` Mark Wielaard
0 siblings, 1 reply; 18+ messages in thread
From: H.J. Lu @ 2021-04-02 13:45 UTC (permalink / raw)
To: Kaylee Blake; +Cc: Binutils, GCC Development, GNU C Library
On Fri, Aug 14, 2020 at 8:25 AM Kaylee Blake <klkblake@gmail.com> wrote:
>
> On 7/8/20 10:41 pm, H.J. Lu wrote:
> > On Tue, May 5, 2020 at 6:42 PM Kaylee Blake <klkblake@gmail.com> wrote:
> >>
> >> On 2/5/20 11:49 pm, H.J. Lu wrote:
> >>> On Wed, Mar 18, 2020 at 6:46 PM Kaylee Blake via Binutils
> >>> <binutils@sourceware.org> wrote:
> >>>>
> >>>> On 19/3/20 12:02 pm, H.J. Lu wrote:
> >>>>> Kaylee, is your paper work with FSF in order? I will submit the updated
> >>>>> patch set after your paper is on file with FSF.
> >>>>
> >>>> I'm waiting on a response from them at the moment.
> >>>>
> >>>
> >>> Hi Kaylee,
> >>>
> >>> Any update on your paper work with FSF?
> >>>
> >>
> >> Still waiting; apparently their work process has been dramatically
> >> slowed by the whole COVID-19 situation.
> >>
> >> --
> >> Kaylee Blake <klkblake@gmail.com>
> >> C is the worst language, except for all the others.
> >
> > Hi,
> >
> > I submitted a set of binutils patches:
> >
> > https://sourceware.org/pipermail/binutils/2020-March/000013.html
> >
> > including contribution from Kaylee Blake <klkblake@gmail.com>.
> > Can someone check if Kaylee's paperwork is on file with FSF?
> >
> > Thanks.
> >
>
> I needed clarification on some of the language in the contract, and with
> them being so busy that has been taking a while. They've confirmed it's
> still in their work queue.
>
> --
> Kaylee Blake <klkblake@gmail.com>
> C is the worst language, except for all the others.
Can someone check if Kaylee's paperwork is on file with FSF?
Thanks.
--
H.J.
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: Has FSF stopped processing copyright paperwork?
2021-04-02 13:45 ` H.J. Lu
@ 2021-04-02 15:21 ` Mark Wielaard
0 siblings, 0 replies; 18+ messages in thread
From: Mark Wielaard @ 2021-04-02 15:21 UTC (permalink / raw)
To: H.J. Lu, Kaylee Blake; +Cc: GCC Development, GNU C Library, Binutils
Hi,
On Fri, 2021-04-02 at 06:45 -0700, H.J. Lu via Gcc wrote:
> On Fri, Aug 14, 2020 at 8:25 AM Kaylee Blake <klkblake@gmail.com> wrote:
> > I needed clarification on some of the language in the contract, and with
> > them being so busy that has been taking a while. They've confirmed it's
> > still in their work queue.
> >
> Can someone check if Kaylee's paperwork is on file with FSF?
I cannot find anything, sorry. It might be best to contact the
Copyright Clerk at fsf-records@gnu.org with any details you can provide
about when and for which name/email address the assignment was
submitted.
Note that it might be a holiday this Friday/Monday over there.
Also the FSF might be a bit busy at the moment with changing its
management team and board:
https://www.fsf.org/blogs/executive-director/management-team-members-resigning
Cheers,
Mark
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 5/7] binutils: Add --remove-section-header tests
2020-03-10 0:12 [PATCH 0/7] ELF: Omit section header on ELF objects H.J. Lu
@ 2020-03-10 0:12 ` H.J. Lu
0 siblings, 0 replies; 18+ messages in thread
From: H.J. Lu @ 2020-03-10 0:12 UTC (permalink / raw)
To: binutils
Verify --remove-section-header with objcopy and strip is ignored for
relocatable file.
PR ld/25617
* testsuite/binutils-all/objcopy.exp: Verify
--remove-section-header ignored for relocatable file.
* testsuite/binutils-all/remove-header-1.d: New file.
---
binutils/testsuite/binutils-all/objcopy.exp | 13 +++++++++++++
| 8 ++++++++
2 files changed, 21 insertions(+)
create mode 100644 binutils/testsuite/binutils-all/remove-header-1.d
diff --git a/binutils/testsuite/binutils-all/objcopy.exp b/binutils/testsuite/binutils-all/objcopy.exp
index 549b064e96..11bb8fea84 100644
--- a/binutils/testsuite/binutils-all/objcopy.exp
+++ b/binutils/testsuite/binutils-all/objcopy.exp
@@ -1115,6 +1115,13 @@ if [is_elf_format] {
run_dump_test "note-6-32"
}
run_dump_test "note-5"
+
+ set saved_OBJCOPYFLAGS $OBJCOPYFLAGS
+ append OBJCOPYFLAGS " --remove-section-header"
+
+ objcopy_test "simple copy with --remove-section-header" bintest.s
+
+ set OBJCOPYFLAGS $saved_OBJCOPYFLAGS
}
run_dump_test "copy-2"
@@ -1231,6 +1238,12 @@ if [is_elf_format] {
verbose [file rootname $t]
run_dump_test [file rootname $t]
}
+
+ # Test --remove-section-header
+ run_dump_test "remove-header-1" \
+ [list \
+ [list source strip-15${reloc_format}.s] \
+ [list as "${elf64} --defsym RELOC=${reloc}"]]
}
run_dump_test "localize-hidden-2"
--git a/binutils/testsuite/binutils-all/remove-header-1.d b/binutils/testsuite/binutils-all/remove-header-1.d
new file mode 100644
index 0000000000..60a9c407af
--- /dev/null
+++ b/binutils/testsuite/binutils-all/remove-header-1.d
@@ -0,0 +1,8 @@
+#PROG: strip
+#strip: -g --remove-section-header
+#readelf: -r
+
+Relocation section '\.rela?\.text' at offset .* contains 2 entries:
+ *Offset * Info * Type * Sym\. *Value * Sym\. *Name(?: * \+ * Addend)?
+0+00 * 0+0(?:1|b|32|103) * R_[^ ]* *(?: * 55aa)?
+#pass
--
2.24.1
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2021-04-02 15:21 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-08 23:42 [PATCH 0/7] ELF: Don't require section header on ELF objects H.J. Lu
2020-03-08 23:42 ` [PATCH 1/7] " H.J. Lu
2020-03-08 23:42 ` [PATCH 2/7] bfd: Reconstruct dynamic symbol table from PT_DYNAMIC segment H.J. Lu
2020-03-08 23:42 ` [PATCH 3/7] readelf: Compute dynamic symbol table size from hash table H.J. Lu
2020-03-08 23:42 ` [PATCH 4/7] ld: Add a simple test for -z nosectionheader H.J. Lu
2020-03-08 23:42 ` [PATCH 5/7] binutils: Add --remove-section-header tests H.J. Lu
2020-03-08 23:42 ` [PATCH 6/7] ld: Add tests for -z nosectionheader and --remove-section-header H.J. Lu
2020-03-08 23:42 ` [PATCH 7/7] ld: Add -z nosectionheader test to bootstrap.exp H.J. Lu
2020-03-19 0:48 ` [PATCH 0/7] ELF: Don't require section header on ELF objects Fangrui Song
2020-03-19 1:32 ` H.J. Lu
2020-03-19 1:45 ` Kaylee Blake
2020-05-02 14:19 ` H.J. Lu
[not found] ` <06c41571-09ef-d107-ee21-38af17f6d20b@gmail.com>
2020-08-07 13:11 ` Has FSF stopped processing copyright paperwork? H.J. Lu
2020-08-07 13:28 ` Richard Biener
2020-08-14 15:25 ` Kaylee Blake
2021-04-02 13:45 ` H.J. Lu
2021-04-02 15:21 ` Mark Wielaard
2020-03-10 0:12 [PATCH 0/7] ELF: Omit section header on ELF objects H.J. Lu
2020-03-10 0:12 ` [PATCH 5/7] binutils: Add --remove-section-header tests H.J. Lu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).