Recognize --eh=frame-hdr option.
authorUlrich Drepper <drepper@redhat.com>
Sun, 11 Jun 2006 09:07:37 +0000 (09:07 +0000)
committerUlrich Drepper <drepper@redhat.com>
Sun, 11 Jun 2006 09:07:37 +0000 (09:07 +0000)
Don't create output sections in executables and DSOs with SHF_GROUP set.

src/ChangeLog
src/ld.c
src/ld.h
src/ldgeneric.c

index 0c876b6..a4cee17 100644 (file)
@@ -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.
index a233764..a0d00fe 100644 (file)
--- 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)
        {
index 1d96481..36afca1 100644 (file)
--- 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.  */
index 07cf3e1..c089e0b 100644 (file)
 #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;