Updated Portuguese translation for the BFD sub-directory
[binutils-gdb.git] / bfd / i386msdos.c
index 3a272e9b61ccda3ce55ee5df2b32f286de8f4fc7..349e8d2bd55d13e5a958bf4f45b065fcd190a091 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD back-end for MS-DOS executables.
 /* BFD back-end for MS-DOS executables.
-   Copyright (C) 1990-2017 Free Software Foundation, Inc.
+   Copyright (C) 1990-2021 Free Software Foundation, Inc.
    Written by Bryan Ford of the University of Utah.
 
    Contributed by the Center for Software Science at the
    Written by Bryan Ford of the University of Utah.
 
    Contributed by the Center for Software Science at the
 #include "bfd.h"
 #include "libbfd.h"
 #include "libaout.h"
 #include "bfd.h"
 #include "libbfd.h"
 #include "libaout.h"
+#include "coff/msdos.h"
 
 
-#define EXE_MAGIC      0x5a4d
 #define EXE_LOAD_HIGH  0x0000
 #define EXE_LOAD_LOW   0xffff
 #define EXE_PAGE_SIZE  512
 
 #define EXE_LOAD_HIGH  0x0000
 #define EXE_LOAD_LOW   0xffff
 #define EXE_PAGE_SIZE  512
 
+static bool
+msdos_mkobject (bfd *abfd)
+{
+  bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_i386_i8086);
+
+  return aout_32_mkobject (abfd);
+}
+
+static bfd_cleanup
+msdos_object_p (bfd *abfd)
+{
+  struct external_DOS_hdr hdr;
+  bfd_byte buffer[2];
+  asection *section;
+  bfd_size_type size;
+
+  if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
+      || (size = bfd_bread (&hdr, sizeof (hdr), abfd)) + 1 < DOS_HDR_SIZE + 1)
+    {
+      if (bfd_get_error () != bfd_error_system_call)
+       bfd_set_error (bfd_error_wrong_format);
+      return NULL;
+    }
+
+  if (H_GET_16 (abfd, hdr.e_magic) != IMAGE_DOS_SIGNATURE)
+    {
+      bfd_set_error (bfd_error_wrong_format);
+      return NULL;
+    }
+
+  /* Check that this isn't actually a PE, NE, or LE file. If it is, the
+     e_lfanew field will be valid and point to a header beginning with one of
+     the relevant signatures.  If not, e_lfanew might point to anything, so
+     don't bail if we can't read there.  */
+  if (size < offsetof (struct external_DOS_hdr, e_lfanew) + 4
+      || H_GET_16 (abfd, hdr.e_cparhdr) < 4)
+    ;
+  else if (bfd_seek (abfd, H_GET_32 (abfd, hdr.e_lfanew), SEEK_SET) != 0
+          || bfd_bread (buffer, (bfd_size_type) 2, abfd) != 2)
+    {
+      if (bfd_get_error () == bfd_error_system_call)
+       return NULL;
+    }
+  else
+    {
+      if (H_GET_16 (abfd, buffer) == IMAGE_NT_SIGNATURE
+         || H_GET_16 (abfd, buffer) == IMAGE_OS2_SIGNATURE
+         || H_GET_16 (abfd, buffer) == IMAGE_OS2_SIGNATURE_LE
+         || H_GET_16 (abfd, buffer) == IMAGE_OS2_SIGNATURE_LX)
+       {
+         bfd_set_error (bfd_error_wrong_format);
+         return NULL;
+       }
+    }
+
+  if (!msdos_mkobject (abfd))
+    return NULL;
+
+  abfd->flags = EXEC_P;
+  abfd->start_address = H_GET_16 (abfd, hdr.e_ip);
+
+  section = bfd_make_section (abfd, ".text");
+  if (section == NULL)
+    return NULL;
+
+  section->flags = (SEC_ALLOC | SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS);
+  section->filepos = H_GET_16 (abfd, hdr.e_cparhdr) * 16;
+  size = (H_GET_16 (abfd, hdr.e_cp) - 1) * EXE_PAGE_SIZE - section->filepos;
+  size += H_GET_16 (abfd, hdr.e_cblp);
+
+  /* Check that the size is valid.  */
+  if (bfd_seek (abfd, section->filepos + size, SEEK_SET) != 0)
+    {
+      if (bfd_get_error () != bfd_error_system_call)
+       bfd_set_error (bfd_error_wrong_format);
+      return NULL;
+    }
+
+  bfd_set_section_size (section, size);
+  section->alignment_power = 4;
+
+  return _bfd_no_cleanup;
+}
+
 static int
 msdos_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
                      struct bfd_link_info *info ATTRIBUTE_UNUSED)
 static int
 msdos_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
                      struct bfd_link_info *info ATTRIBUTE_UNUSED)
@@ -40,7 +124,7 @@ msdos_sizeof_headers (bfd *abfd ATTRIBUTE_UNUSED,
   return 0;
 }
 
   return 0;
 }
 
-static bfd_boolean
+static bool
 msdos_write_object_contents (bfd *abfd)
 {
   static char hdr[EXE_PAGE_SIZE];
 msdos_write_object_contents (bfd *abfd)
 {
   static char hdr[EXE_PAGE_SIZE];
@@ -53,16 +137,16 @@ msdos_write_object_contents (bfd *abfd)
     {
       if (sec->size == 0)
        continue;
     {
       if (sec->size == 0)
        continue;
-      if (bfd_get_section_flags (abfd, sec) & SEC_ALLOC)
+      if (bfd_section_flags (sec) & SEC_ALLOC)
        {
        {
-         bfd_vma sec_vma = bfd_get_section_vma (abfd, sec) + sec->size;
+         bfd_vma sec_vma = bfd_section_vma (sec) + sec->size;
          if (sec_vma > high_vma)
            high_vma = sec_vma;
        }
          if (sec_vma > high_vma)
            high_vma = sec_vma;
        }
-      if (bfd_get_section_flags (abfd, sec) & SEC_LOAD)
+      if (bfd_section_flags (sec) & SEC_LOAD)
        {
          file_ptr sec_end = (sizeof (hdr)
        {
          file_ptr sec_end = (sizeof (hdr)
-                             + bfd_get_section_vma (abfd, sec)
+                             + bfd_section_vma (sec)
                              + sec->size);
          if (sec_end > outfile_size)
            outfile_size = sec_end;
                              + sec->size);
          if (sec_end > outfile_size)
            outfile_size = sec_end;
@@ -73,11 +157,11 @@ msdos_write_object_contents (bfd *abfd)
   if (high_vma > (bfd_vma)0xffff)
     {
       bfd_set_error(bfd_error_file_too_big);
   if (high_vma > (bfd_vma)0xffff)
     {
       bfd_set_error(bfd_error_file_too_big);
-      return FALSE;
+      return false;
     }
 
   /* Constants.  */
     }
 
   /* Constants.  */
-  H_PUT_16 (abfd, EXE_MAGIC, &hdr[0]);
+  H_PUT_16 (abfd, IMAGE_DOS_SIGNATURE, &hdr[0]);
   H_PUT_16 (abfd, EXE_PAGE_SIZE / 16, &hdr[8]);
   H_PUT_16 (abfd, EXE_LOAD_LOW, &hdr[12]);
   H_PUT_16 (abfd, 0x3e, &hdr[24]);
   H_PUT_16 (abfd, EXE_PAGE_SIZE / 16, &hdr[8]);
   H_PUT_16 (abfd, EXE_LOAD_LOW, &hdr[12]);
   H_PUT_16 (abfd, 0x3e, &hdr[24]);
@@ -97,12 +181,12 @@ msdos_write_object_contents (bfd *abfd)
 
   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
       || bfd_bwrite (hdr, (bfd_size_type) sizeof(hdr), abfd) != sizeof(hdr))
 
   if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0
       || bfd_bwrite (hdr, (bfd_size_type) sizeof(hdr), abfd) != sizeof(hdr))
-    return FALSE;
+    return false;
 
 
-  return TRUE;
+  return true;
 }
 
 }
 
-static bfd_boolean
+static bool
 msdos_set_section_contents (bfd *abfd,
                            sec_ptr section,
                            const void *location,
 msdos_set_section_contents (bfd *abfd,
                            sec_ptr section,
                            const void *location,
@@ -111,23 +195,22 @@ msdos_set_section_contents (bfd *abfd,
 {
 
   if (count == 0)
 {
 
   if (count == 0)
-    return TRUE;
+    return true;
 
 
-  section->filepos = EXE_PAGE_SIZE + bfd_get_section_vma (abfd, section);
+  section->filepos = EXE_PAGE_SIZE + bfd_section_vma (section);
 
 
-  if (bfd_get_section_flags (abfd, section) & SEC_LOAD)
+  if (bfd_section_flags (section) & SEC_LOAD)
     {
       if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
          || bfd_bwrite (location, count, abfd) != count)
     {
       if (bfd_seek (abfd, section->filepos + offset, SEEK_SET) != 0
          || bfd_bwrite (location, count, abfd) != count)
-       return FALSE;
+       return false;
     }
 
     }
 
-  return TRUE;
+  return true;
 }
 
 
 
 }
 
 
 
-#define msdos_mkobject aout_32_mkobject
 #define msdos_make_empty_symbol aout_32_make_empty_symbol
 #define msdos_bfd_reloc_type_lookup aout_32_reloc_type_lookup
 #define msdos_bfd_reloc_name_lookup aout_32_reloc_name_lookup
 #define msdos_make_empty_symbol aout_32_make_empty_symbol
 #define msdos_bfd_reloc_type_lookup aout_32_reloc_type_lookup
 #define msdos_bfd_reloc_name_lookup aout_32_reloc_name_lookup
@@ -145,10 +228,12 @@ msdos_set_section_contents (bfd *abfd,
 #define msdos_bfd_lookup_section_flags bfd_generic_lookup_section_flags
 #define msdos_bfd_merge_sections bfd_generic_merge_sections
 #define msdos_bfd_is_group_section bfd_generic_is_group_section
 #define msdos_bfd_lookup_section_flags bfd_generic_lookup_section_flags
 #define msdos_bfd_merge_sections bfd_generic_merge_sections
 #define msdos_bfd_is_group_section bfd_generic_is_group_section
+#define msdos_bfd_group_name bfd_generic_group_name
 #define msdos_bfd_discard_group bfd_generic_discard_group
 #define msdos_section_already_linked \
   _bfd_generic_section_already_linked
 #define msdos_bfd_define_common_symbol bfd_generic_define_common_symbol
 #define msdos_bfd_discard_group bfd_generic_discard_group
 #define msdos_section_already_linked \
   _bfd_generic_section_already_linked
 #define msdos_bfd_define_common_symbol bfd_generic_define_common_symbol
+#define msdos_bfd_link_hide_symbol _bfd_generic_link_hide_symbol
 #define msdos_bfd_define_start_stop bfd_generic_define_start_stop
 #define msdos_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
 #define msdos_bfd_link_add_symbols _bfd_generic_link_add_symbols
 #define msdos_bfd_define_start_stop bfd_generic_define_start_stop
 #define msdos_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
 #define msdos_bfd_link_add_symbols _bfd_generic_link_add_symbols
@@ -170,7 +255,7 @@ msdos_set_section_contents (bfd *abfd,
 #define msdos_find_line _bfd_nosymbols_find_line
 #define msdos_find_inliner_info _bfd_nosymbols_find_inliner_info
 #define msdos_get_lineno _bfd_nosymbols_get_lineno
 #define msdos_find_line _bfd_nosymbols_find_line
 #define msdos_find_inliner_info _bfd_nosymbols_find_inliner_info
 #define msdos_get_lineno _bfd_nosymbols_get_lineno
-#define msdos_bfd_is_target_special_symbol ((bfd_boolean (*) (bfd *, asymbol *)) bfd_false)
+#define msdos_bfd_is_target_special_symbol _bfd_bool_bfd_asymbol_false
 #define msdos_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
 #define msdos_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
 #define msdos_read_minisymbols _bfd_nosymbols_read_minisymbols
 #define msdos_bfd_is_local_label_name _bfd_nosymbols_bfd_is_local_label_name
 #define msdos_bfd_make_debug_symbol _bfd_nosymbols_bfd_make_debug_symbol
 #define msdos_read_minisymbols _bfd_nosymbols_read_minisymbols
@@ -194,6 +279,7 @@ const bfd_target i386_msdos_vec =
     ' ',                               /* ar_pad_char */
     16,                                /* ar_max_namelen */
     0,                         /* match priority.  */
     ' ',                               /* ar_pad_char */
     16,                                /* ar_max_namelen */
     0,                         /* match priority.  */
+    TARGET_KEEP_UNUSED_SECTION_SYMBOLS, /* keep unused section symbols.  */
     bfd_getl64, bfd_getl_signed_64, bfd_putl64,
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
     bfd_getl16, bfd_getl_signed_16, bfd_putl16,        /* data */
     bfd_getl64, bfd_getl_signed_64, bfd_putl64,
     bfd_getl32, bfd_getl_signed_32, bfd_putl32,
     bfd_getl16, bfd_getl_signed_16, bfd_putl16,        /* data */
@@ -203,21 +289,21 @@ const bfd_target i386_msdos_vec =
 
     {
       _bfd_dummy_target,
 
     {
       _bfd_dummy_target,
-      _bfd_dummy_target,               /* bfd_check_format */
+      msdos_object_p,          /* bfd_check_format */
       _bfd_dummy_target,
       _bfd_dummy_target,
     },
     {
       _bfd_dummy_target,
       _bfd_dummy_target,
     },
     {
-      bfd_false,
+      _bfd_bool_bfd_false_error,
       msdos_mkobject,
       _bfd_generic_mkarchive,
       msdos_mkobject,
       _bfd_generic_mkarchive,
-      bfd_false,
+      _bfd_bool_bfd_false_error,
     },
     {                          /* bfd_write_contents */
     },
     {                          /* bfd_write_contents */
-      bfd_false,
+      _bfd_bool_bfd_false_error,
       msdos_write_object_contents,
       _bfd_write_archive_contents,
       msdos_write_object_contents,
       _bfd_write_archive_contents,
-      bfd_false,
+      _bfd_bool_bfd_false_error,
     },
 
     BFD_JUMP_TABLE_GENERIC (msdos),
     },
 
     BFD_JUMP_TABLE_GENERIC (msdos),