summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2006-06-11 09:07:37 +0000
committerUlrich Drepper <drepper@redhat.com>2006-06-11 09:07:37 +0000
commit54f33a779527d6764b4fc4068267715a718c422c (patch)
treebd4ffaa0168671f0909ff2ea5fffc0d9bb8e639e /src
parent4f0a7a89be199fa86d9c5c7a56f4be9c5cfb2a4e (diff)
downloadelfutils-54f33a779527d6764b4fc4068267715a718c422c.tar.gz
Recognize --eh=frame-hdr option.
Don't create output sections in executables and DSOs with SHF_GROUP set.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog11
-rw-r--r--src/ld.c8
-rw-r--r--src/ld.h3
-rw-r--r--src/ldgeneric.c32
4 files changed, 45 insertions, 9 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 0c876b6f..a4cee179 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,14 @@
+2006-06-11 Ulrich Drepper <drepper@redhat.com>
+
+ * ld.c: Recognize --eh-frame-hdr option.
+ * ld.h (struct ld_state): Add eh_frame_hdr field.
+ * ldgeneric.c (struct unw_eh_frame_hdr): Define.
+
+ * ldgeneric.c (add_section): Use ebl_sh_flags_combine instead of
+ SH_FLAGS_COMBINE.
+ (add_relocatable_file): Minor optimization of last change.
+ (match_section): Don't preserve SHF_GROUP flag any longer.
+
2006-06-10 Ulrich Drepper <drepper@redhat.com>
* ld.c (parse_z_option): Recognize execstack and noexecstack.
diff --git a/src/ld.c b/src/ld.c
index a233764f..a0d00fe2 100644
--- a/src/ld.c
+++ b/src/ld.c
@@ -73,6 +73,7 @@ enum
ARGP_conserve,
ARGP_as_needed,
ARGP_no_as_needed,
+ ARGP_eh_frame_hdr,
#if YYDEBUG
ARGP_yydebug,
#endif
@@ -199,6 +200,9 @@ Default rules of extracting from archive; weak references are not enough."),
{ "no-as-needed", ARGP_no_as_needed, NULL, 0,
N_("Always set DT_NEEDED for following dynamic libs"), 0 },
+ { "eh-frame-hdr", ARGP_eh_frame_hdr, NULL, 0,
+ N_("Create .eh_frame_hdr section"), 0 },
+
#if YYDEBUG
{ "yydebug", ARGP_yydebug, NULL, 0,
N_("Select to get parser debug information"), 0 },
@@ -627,6 +631,10 @@ parse_opt_1st (int key, char *arg,
ld_state.gc_sections = key == ARGP_gc_sections;
break;
+ case ARGP_eh_frame_hdr:
+ ld_state.eh_frame_hdr = true;
+ break;
+
case 's':
if (arg == NULL)
{
diff --git a/src/ld.h b/src/ld.h
index 1d964814..36afca13 100644
--- a/src/ld.h
+++ b/src/ld.h
@@ -1007,6 +1007,9 @@ struct ld_state
/* Lazy-loading state for dependencies. */
bool lazyload;
+ /* True if an .eh_frame_hdr section should be generated. */
+ bool eh_frame_hdr;
+
/* True if in executables all global symbols should be exported in
the dynamic symbol table. */
diff --git a/src/ldgeneric.c b/src/ldgeneric.c
index 07cf3e19..c089e0ba 100644
--- a/src/ldgeneric.c
+++ b/src/ldgeneric.c
@@ -49,6 +49,17 @@
#include "list.h"
+/* Header of .eh_frame_hdr section. */
+struct unw_eh_frame_hdr
+{
+ unsigned char version;
+ unsigned char eh_frame_ptr_enc;
+ unsigned char fde_count_enc;
+ unsigned char table_enc;
+};
+#define EH_FRAME_HDR_VERSION 1
+
+
/* Prototypes for local functions. */
static const char **ld_generic_lib_extensions (struct ld_state *)
__attribute__ ((__const__));
@@ -989,7 +1000,8 @@ add_section (struct usedfiles *fileinfo, struct scninfo *scninfo)
scninfo->next = queued->last->next;
queued->last = queued->last->next = scninfo;
- queued->flags = SH_FLAGS_COMBINE (queued->flags, shdr->sh_flags);
+ queued->flags = ebl_sh_flags_combine (ld_state.ebl, queued->flags,
+ shdr->sh_flags);
queued->align = MAX (queued->align, shdr->sh_addralign);
}
}
@@ -1240,13 +1252,11 @@ add_relocatable_file (struct usedfiles *fileinfo, GElf_Word secttype)
{
/* Check whether the check needs to be executable. */
if (shdr->sh_type == SHT_PROGBITS
+ && (shdr->sh_flags & SHF_EXECINSTR) == 0
&& strcmp (elf_strptr (fileinfo->elf, fileinfo->shstrndx,
shdr->sh_name),
- ".note.GNU-stack") == 0
- && (shdr->sh_flags & SHF_EXECINSTR) == 0)
+ ".note.GNU-stack") == 0)
execstack = execstack_false;
- printf("%s %d\n", elf_strptr (fileinfo->elf, fileinfo->shstrndx,
- shdr->sh_name),(int)execstack);
add_section (fileinfo, &fileinfo->scninfo[cnt]);
}
@@ -1258,7 +1268,6 @@ add_relocatable_file (struct usedfiles *fileinfo, GElf_Word secttype)
&& execstack == execstack_true
&& ld_state.execstack != execstack_false_force)
ld_state.execstack = execstack_true;
- printf("%s: state = %d\n", fileinfo->fname,(int)ld_state.execstack);
/* Handle the symbols. Record defined and undefined symbols in the
hash table. In theory there can be a file without any symbol
@@ -2686,7 +2695,7 @@ match_section (const char *osectname, struct filemask_section_name *sectmask,
const char *brfname = basename (runp->fileinfo->rfname);
/* If the section isn't used, the name doesn't match the positive
- inclusion list or the name does match the negative inclusion
+ inclusion list, or the name does match the negative inclusion
list, ignore the section. */
if (!runp->used
|| (sectmask->filemask != NULL
@@ -2731,7 +2740,9 @@ match_section (const char *osectname, struct filemask_section_name *sectmask,
newp->kind = scn_normal;
newp->name = osectname;
newp->type = SCNINFO_SHDR (found->shdr).sh_type;
- newp->flags = SCNINFO_SHDR (found->shdr).sh_flags;
+ /* Executable or DSO do not have section groups. Drop that
+ information. */
+ newp->flags = SCNINFO_SHDR (found->shdr).sh_flags & ~SHF_GROUP;
newp->segment_nr = segment_nr;
newp->last = found->next = found;
newp->used = true;
@@ -2762,9 +2773,12 @@ match_section (const char *osectname, struct filemask_section_name *sectmask,
/* XXX Any better choice? */
queued->type = SHT_PROGBITS;
if (queued->flags != SCNINFO_SHDR (found->shdr).sh_flags)
+ /* Executable or DSO do not have section groups. Drop that
+ information. */
queued->flags = ebl_sh_flags_combine (ld_state.ebl,
queued->flags,
- SCNINFO_SHDR (found->shdr).sh_flags);
+ SCNINFO_SHDR (found->shdr).sh_flags
+ & ~SHF_GROUP);
/* Accumulate the relocation section size. */
queued->relsize += found->relsize;