Patch from: Jim Pick <jim@jimpick.com>
[deliverable/binutils-gdb.git] / ld / emultempl / armelf.em
index 6512ee38c41234b487cf6cac86d01841297797bf..88d7e270370c8c1a5359094afe155ed6f93c28f2 100644 (file)
@@ -65,13 +65,18 @@ static void gld${EMULATION_NAME}_before_allocation PARAMS ((void));
 static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
 static int  gld${EMULATION_NAME}_parse_args PARAMS((int, char **));
 static void gld${EMULATION_NAME}_list_options PARAMS ((FILE *));
+static void gld_${EMULATION_NAME}_finish PARAMS ((void));
 
 \f
 static int no_pipeline_knowledge = 0;
+static char * thumb_entry_symbol = NULL;
+
+#define OPTION_THUMB_ENTRY             301
 
 static struct option longopts[] =
 {
   { "no-pipeline-knowledge", no_argument, NULL, 'p'},
+  { "thumb-entry", required_argument, NULL, OPTION_THUMB_ENTRY},
   { NULL, no_argument, NULL, 0 }
 };
 
@@ -80,6 +85,7 @@ gld${EMULATION_NAME}_list_options (file)
      FILE * file;
 {
   fprintf (file, _("  -p --no-pipeline-knowledge  Stop the linker knowing about the pipeline length\n"));
+  fprintf (file, _("     --thumb-entry=<sym>      Set the entry point to be Thumb symbol <sym>\n"));
 }
 
 static int
@@ -114,6 +120,10 @@ gld${EMULATION_NAME}_parse_args (argc, argv)
     case 'p':
       no_pipeline_knowledge = 1;
       break;
+
+    case OPTION_THUMB_ENTRY:
+      thumb_entry_symbol = optarg;
+      break;
     }
   
   return 1;
@@ -193,7 +203,8 @@ gld${EMULATION_NAME}_open_dynamic_archive (arch, search, entry)
 
 EOF
 if [ "x${host}" = "x${target}" ] ; then
-  if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then
+  case " ${EMULATION_LIBPATH} " in
+  *" ${EMULATION_NAME} "*)
 cat >>e${EMULATION_NAME}.c <<EOF
 
 /* For a native linker, check the file /etc/ld.so.conf for directories
@@ -278,7 +289,8 @@ gld${EMULATION_NAME}_check_ld_so_conf (name, force)
 }
 
 EOF
-  fi
+  ;;
+  esac
 fi
 cat >>e${EMULATION_NAME}.c <<EOF
 
@@ -368,13 +380,15 @@ gld${EMULATION_NAME}_after_open ()
            }
 EOF
 if [ "x${host}" = "x${target}" ] ; then
-  if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then
+  case " ${EMULATION_LIBPATH} " in
+  *" ${EMULATION_NAME} "*)
 cat >>e${EMULATION_NAME}.c <<EOF
          lib_path = (const char *) getenv ("LD_LIBRARY_PATH");
          if (gld${EMULATION_NAME}_search_needed (lib_path, l->name, force))
            break;
 EOF
-  fi
+  ;;
+  esac
 fi
 cat >>e${EMULATION_NAME}.c <<EOF
          len = strlen (l->name);
@@ -394,12 +408,14 @@ cat >>e${EMULATION_NAME}.c <<EOF
            break;
 EOF
 if [ "x${host}" = "x${target}" ] ; then
-  if [ "x${DEFAULT_EMULATION}" = "x${EMULATION_NAME}" ] ; then
+  case " ${EMULATION_LIBPATH} " in
+  *" ${EMULATION_NAME} "*)
 cat >>e${EMULATION_NAME}.c <<EOF
          if (gld${EMULATION_NAME}_check_ld_so_conf (l->name, force))
            break;
 EOF
-  fi
+  ;;
+  esac
 fi
 cat >>e${EMULATION_NAME}.c <<EOF
        }
@@ -1130,6 +1146,49 @@ gld${EMULATION_NAME}_before_allocation ()
   bfd_elf32_arm_allocate_interworking_sections (& link_info);
 }
 
+static void
+gld${EMULATION_NAME}_finish PARAMS((void))
+{
+  struct bfd_link_hash_entry * h;
+
+  if (thumb_entry_symbol == NULL)
+    return;
+  
+  h = bfd_link_hash_lookup (link_info.hash, thumb_entry_symbol, false, false, true);
+
+  if (h != (struct bfd_link_hash_entry *) NULL
+      && (h->type == bfd_link_hash_defined
+         || h->type == bfd_link_hash_defweak)
+      && h->u.def.section->output_section != NULL)
+    {
+      static char buffer[32];
+      bfd_vma val;
+      
+      /* Special procesing is required for a Thumb entry symbol.  The
+        bottom bit of its address must be set.  */
+      val = (h->u.def.value
+            + bfd_get_section_vma (output_bfd,
+                                   h->u.def.section->output_section)
+            + h->u.def.section->output_offset);
+      
+      val |= 1;
+
+      /* Now convert this value into a string and store it in entry_symbol
+         where the lang_finish() function will pick it up.  */
+      buffer[0] = '0';
+      buffer[1] = 'x';
+      
+      sprintf_vma (buffer + 2, val);
+
+      if (entry_symbol != NULL && entry_from_cmdline)
+       einfo (_("%P: warning: '--thumb-entry %s' is overriding '-e %s'\n"),
+              thumb_entry_symbol, entry_symbol);
+      entry_symbol = buffer;
+    }
+  else
+    einfo (_("%P: warning: connot find thumb start symbol %s\n"), thumb_entry_symbol);
+}
+
 static char *
 gld${EMULATION_NAME}_get_script (isfile)
      int *isfile;
@@ -1156,6 +1215,10 @@ echo '  ; else if (!config.text_read_only) return'         >> e${EMULATION_NAME}
 sed $sc ldscripts/${EMULATION_NAME}.xbn                    >> e${EMULATION_NAME}.c
 echo '  ; else if (!config.magic_demand_paged) return'     >> e${EMULATION_NAME}.c
 sed $sc ldscripts/${EMULATION_NAME}.xn                     >> e${EMULATION_NAME}.c
+if test -n "$GENERATE_SHLIB_SCRIPT" ; then
+        echo '  ; else if (link_info.shared) return'       >> e${EMULATION_NAME}.c
+        sed $sc ldscripts/${EMULATION_NAME}.xs             >> e${EMULATION_NAME}.c
+fi
 echo '  ; else return'                                     >> e${EMULATION_NAME}.c
 sed $sc ldscripts/${EMULATION_NAME}.x                      >> e${EMULATION_NAME}.c
 echo '; }'                                                 >> e${EMULATION_NAME}.c
@@ -1175,6 +1238,8 @@ cat >>e${EMULATION_NAME}.c <<EOF
     return "ldscripts/${EMULATION_NAME}.xbn";
   else if (!config.magic_demand_paged)
     return "ldscripts/${EMULATION_NAME}.xn";
+  else if (link_info.shared)
+    return "ldscripts/${EMULATION_NAME}.xs";
   else
     return "ldscripts/${EMULATION_NAME}.x";
 }
@@ -1198,7 +1263,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
   gld${EMULATION_NAME}_get_script,
   "${EMULATION_NAME}",
   "${OUTPUT_FORMAT}",
-  NULL, /* finish */
+  gld${EMULATION_NAME}_finish, /* finish */
   NULL, /* create output section statements */
   gld${EMULATION_NAME}_open_dynamic_archive,
   gld${EMULATION_NAME}_place_orphan,
This page took 0.044003 seconds and 4 git commands to generate.