From 1fdf02497c16f3f011e3548c4bb810b26ac670b9 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Thu, 6 Sep 2001 15:20:01 +0000 Subject: [PATCH] Fix import symbols for AIX. --- bfd/ChangeLog | 11 +++++ bfd/bfd-in.h | 5 +- bfd/bfd-in2.h | 5 +- bfd/libxcoff.h | 5 +- bfd/xcofflink.c | 36 ++++++++++++-- include/coff/ChangeLog | 4 ++ include/coff/xcoff.h | 10 +++- ld/ChangeLog | 4 ++ ld/emultempl/aix.em | 110 ++++++++++++++++++----------------------- 9 files changed, 114 insertions(+), 76 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index ffc81da2cbc..8e056f93813 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,14 @@ +2001-09-05 Tom Rix + + * xcofflink.c (bfd_xcoff_import_symbol): Handle import file XMC_XO + and syscall symbols. + (write_global_symbol) : Same. + (bfd_xcoff_export_symbol): Remove unused syscall param. + * libxcoff.h: Change prototype of bfd_xcoff_export symbol and + bfd_xcoff_import_symbol. + * bfd-in.h: Same. + * bfd-in2.h : Regenerate. + 2001-09-04 Richard Henderson * elf64-alpha.c (SKIP_HOWTO): New. diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index 6d4293ee982..079761fc279 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -722,10 +722,9 @@ extern boolean bfd_xcoff_link_record_set bfd_size_type)); extern boolean bfd_xcoff_import_symbol PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, - bfd_vma, const char *, const char *, const char *)); + bfd_vma, const char *, const char *, const char *, unsigned int)); extern boolean bfd_xcoff_export_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, - boolean)); + PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *)); extern boolean bfd_xcoff_link_count_reloc PARAMS ((bfd *, struct bfd_link_info *, const char *)); extern boolean bfd_xcoff_record_link_assignment diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 148fcaa272f..b725dd42adb 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -722,10 +722,9 @@ extern boolean bfd_xcoff_link_record_set bfd_size_type)); extern boolean bfd_xcoff_import_symbol PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, - bfd_vma, const char *, const char *, const char *)); + bfd_vma, const char *, const char *, const char *, unsigned int)); extern boolean bfd_xcoff_export_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, - boolean)); + PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *)); extern boolean bfd_xcoff_link_count_reloc PARAMS ((bfd *, struct bfd_link_info *, const char *)); extern boolean bfd_xcoff_record_link_assignment diff --git a/bfd/libxcoff.h b/bfd/libxcoff.h index 83a65924c64..cbc0bfca948 100644 --- a/bfd/libxcoff.h +++ b/bfd/libxcoff.h @@ -248,10 +248,9 @@ extern boolean bfd_xcoff_link_record_set bfd_size_type)); extern boolean bfd_xcoff_import_symbol PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, - bfd_vma, const char *, const char *, const char *)); + bfd_vma, const char *, const char *, const char *, unsigned int)); extern boolean bfd_xcoff_export_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *, - boolean)); + PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_hash_entry *)); extern boolean bfd_xcoff_link_count_reloc PARAMS ((bfd *, struct bfd_link_info *, const char *)); extern boolean bfd_xcoff_record_link_assignment diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c index ec4257c91b5..6f70a32bd62 100644 --- a/bfd/xcofflink.c +++ b/bfd/xcofflink.c @@ -2514,7 +2514,7 @@ bfd_xcoff_link_record_set (output_bfd, info, harg, size) boolean bfd_xcoff_import_symbol (output_bfd, info, harg, val, imppath, impfile, - impmember) + impmember, syscall_flag) bfd *output_bfd; struct bfd_link_info *info; struct bfd_link_hash_entry *harg; @@ -2522,6 +2522,7 @@ bfd_xcoff_import_symbol (output_bfd, info, harg, val, imppath, impfile, const char *imppath; const char *impfile; const char *impmember; + unsigned int syscall_flag; { struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg; @@ -2564,7 +2565,7 @@ bfd_xcoff_import_symbol (output_bfd, info, harg, val, imppath, impfile, h = hds; } - h->flags |= XCOFF_IMPORT; + h->flags |= (XCOFF_IMPORT | syscall_flag); if (val != (bfd_vma) -1) { @@ -2631,11 +2632,10 @@ bfd_xcoff_import_symbol (output_bfd, info, harg, val, imppath, impfile, /* Export a symbol. */ boolean -bfd_xcoff_export_symbol (output_bfd, info, harg, syscall) +bfd_xcoff_export_symbol (output_bfd, info, harg) bfd *output_bfd; struct bfd_link_info *info; struct bfd_link_hash_entry *harg; - boolean syscall ATTRIBUTE_UNUSED; { struct xcoff_link_hash_entry *h = (struct xcoff_link_hash_entry *) harg; @@ -5334,7 +5334,10 @@ xcoff_write_global_symbol (h, p) if (((h->flags & XCOFF_DEF_REGULAR) == 0 && (h->flags & XCOFF_DEF_DYNAMIC) != 0) || (h->flags & XCOFF_IMPORT) != 0) { - ldsym->l_smtype |= L_IMPORT; + /* Clear l_smtype + Import symbols are defined so the check above will make the l_smtype + XTY_SD. But this is not correct, it should be cleared. */ + ldsym->l_smtype = L_IMPORT; } if (((h->flags & XCOFF_DEF_REGULAR) != 0 && @@ -5353,6 +5356,29 @@ xcoff_write_global_symbol (h, p) ldsym->l_smclas = h->smclas; + if (ldsym->l_smtype & L_IMPORT) + { + if ((h->root.type == bfd_link_hash_defined || + h->root.type == bfd_link_hash_defweak) && + (h->root.u.def.value != 0)) + { + ldsym->l_smclas = XMC_XO; + } + else if ((h->flags & (XCOFF_SYSCALL32 | XCOFF_SYSCALL64)) == + (XCOFF_SYSCALL32 | XCOFF_SYSCALL64)) + { + ldsym->l_smclas = XMC_SV3264; + } + else if (h->flags & XCOFF_SYSCALL32) + { + ldsym->l_smclas = XMC_SV; + } + else if (h->flags & XCOFF_SYSCALL64) + { + ldsym->l_smclas = XMC_SV64; + } + } + if (ldsym->l_ifile == (bfd_size_type) -1) { ldsym->l_ifile = 0; diff --git a/include/coff/ChangeLog b/include/coff/ChangeLog index 498cb265b81..6577b5b6798 100644 --- a/include/coff/ChangeLog +++ b/include/coff/ChangeLog @@ -1,3 +1,7 @@ +2001-09-05 Tom Rix + + * xcoff.h : Add XCOFF_SYSCALL32 and XCOFF_SYSCALL64 hash table flags. + 2001-08-27 Andreas Jaeger * xcoff.h (struct __rtinit): Make proper prototype for rtl. diff --git a/include/coff/xcoff.h b/include/coff/xcoff.h index 508ddfaa214..b25c2945c5b 100644 --- a/include/coff/xcoff.h +++ b/include/coff/xcoff.h @@ -122,6 +122,8 @@ /* 14 ??? */ #define XMC_TC0 15 /* Read-write TOC anchor */ #define XMC_TD 16 /* Read-write data in TOC */ +#define XMC_SV64 17 /* Read-only 64 bit supervisor call */ +#define XMC_SV3264 18 /* Read-only 32 or 64 bit supervisor call */ /* The ldhdr structure. This appears at the start of the .loader section. */ @@ -305,6 +307,11 @@ struct xcoff_link_hash_entry * XCOFF_RTINIT * Symbol is the __rtinit symbol * + * XCOFF_SYSCALL32 + * Symbol is an imported 32 bit syscall + * + * XCOFF_SYSCALL64 + * Symbol is an imported 64 bit syscall */ #define XCOFF_REF_REGULAR 0x00000001 @@ -322,7 +329,8 @@ struct xcoff_link_hash_entry #define XCOFF_DESCRIPTOR 0x00001000 #define XCOFF_MULTIPLY_DEFINED 0x00002000 #define XCOFF_RTINIT 0x00004000 - +#define XCOFF_SYSCALL32 0x00008000 +#define XCOFF_SYSCALL64 0x00010000 /* The XCOFF linker hash table. */ diff --git a/ld/ChangeLog b/ld/ChangeLog index 0c25d4dab6a..78e4ec0771a 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -3,6 +3,10 @@ * ld.texinfo (Options, --stack): Correct default value for stack reserve. +2001-09-05 Tom Rix + + * emultempl/aix.em : Handle import file XMC_XO and syscall symbols. + 2001-09-03 Andreas Jaeger * emultempl/beos.em: Declare prototypes for comparions functions, diff --git a/ld/emultempl/aix.em b/ld/emultempl/aix.em index 3d1c0186580..775a678a4b3 100644 --- a/ld/emultempl/aix.em +++ b/ld/emultempl/aix.em @@ -108,7 +108,6 @@ struct export_symbol_list { struct export_symbol_list *next; const char *name; - boolean syscall; }; static struct export_symbol_list *export_symbols; @@ -642,7 +641,7 @@ gld${EMULATION_NAME}_before_allocation () h = bfd_link_hash_lookup (link_info.hash, el->name, false, false, false); if (h == NULL) einfo ("%P%F: bfd_link_hash_lookup of export symbol failed: %E\n"); - if (! bfd_xcoff_export_symbol (output_bfd, &link_info, h, el->syscall)) + if (! bfd_xcoff_export_symbol (output_bfd, &link_info, h)) einfo ("%P%F: bfd_xcoff_export_symbol failed: %E\n"); } @@ -842,8 +841,7 @@ static int change_symbol_mode (char *input) return 0; } - -static int is_syscall (char *input) +static int is_syscall(char *input, unsigned int *flag) { /* * 1 : yes @@ -852,45 +850,44 @@ static int is_syscall (char *input) */ unsigned int bit; char *string; - - char *syscall_string[] = { - "svc", /* 0x01 */ - "svc32", /* 0x02 */ - "svc3264", /* 0x04 */ - "svc64", /* 0x08 */ - "syscall", /* 0x10 */ - "syscall32", /* 0x20 */ - "syscall3264", /* 0x40 */ - "syscall64", /* 0x80 */ - NULL + + struct sc { + char *syscall_string; + unsigned int flag; + } s [] = { + { "svc" /* 0x01 */, XCOFF_SYSCALL32 }, + { "svc32" /* 0x02 */, XCOFF_SYSCALL32 }, + { "svc3264" /* 0x04 */, XCOFF_SYSCALL32 | XCOFF_SYSCALL64 }, + { "svc64" /* 0x08 */, XCOFF_SYSCALL64 }, + { "syscall" /* 0x10 */, XCOFF_SYSCALL32 }, + { "syscall32" /* 0x20 */, XCOFF_SYSCALL32 }, + { "syscall3264" /* 0x40 */, XCOFF_SYSCALL32 | XCOFF_SYSCALL64 }, + { "syscall64" /* 0x80 */, XCOFF_SYSCALL64 }, + { NULL, 0 }, }; - for (bit = 0; ;bit++) - { + *flag = 0; - string = syscall_string[bit]; - if (NULL == string) - { - return -1; - } - - if (0 == strcmp (input, string)) - { - if (1 << bit & ${SYSCALL_MASK}) - { - return 1; - } - else - { - return 0; - } - } + for (bit = 0; ;bit++) { + + string = s[bit].syscall_string; + if (NULL == string) { + return -1; } + + if (0 == strcmp(input, string)) { + if (1 << bit & ${SYSCALL_MASK}) { + *flag = s[bit].flag; + return 1; + } else { + return 0; + } + } + } /* should not be here */ return -1; } - /* Read an import or export file. For an import file, this is called by the before_allocation emulation routine. For an export file, this is called by the parse_args emulation routine. */ @@ -939,7 +936,7 @@ gld${EMULATION_NAME}_read_file (filename, import) { char *s; char *symname; - boolean syscall; + unsigned int syscall_flag = 0; bfd_vma address; struct bfd_link_hash_entry *h; @@ -1042,7 +1039,7 @@ gld${EMULATION_NAME}_read_file (filename, import) { /* This is a symbol to be imported or exported. */ symname = s; - syscall = false; + syscall_flag = 0; address = (bfd_vma) -1; while (! isspace ((unsigned char) *s) && *s != '\0') @@ -1074,29 +1071,21 @@ gld${EMULATION_NAME}_read_file (filename, import) int status; char *end; - status = is_syscall (s); + status = is_syscall(s, &syscall_flag); + + if (0 > status) { + /* not a system call, check for address */ + address = strtoul (s, &end, 0); - switch (status) - { - case 1: - /* this is a system call */ - syscall = true; - break; - - case 0: - /* ignore this system call */ - break; - - default: - /* not a system call, check for address */ - address = strtoul (s, &end, 0); - if (*end != '\0') - { - einfo ("%s:%d: warning: syntax error in import/export file\n", - filename, lineno); - - } - } + /* not a system call, check for address */ + address = strtoul (s, &end, 0); + if (*end != '\0') + { + einfo ("%s:%d: warning: syntax error in import/export file\n", + filename, lineno); + + } + } } } @@ -1109,7 +1098,6 @@ gld${EMULATION_NAME}_read_file (filename, import) xmalloc (sizeof (struct export_symbol_list))); n->next = export_symbols; n->name = xstrdup (symname); - n->syscall = syscall; export_symbols = n; } else @@ -1125,7 +1113,7 @@ gld${EMULATION_NAME}_read_file (filename, import) { if (! bfd_xcoff_import_symbol (output_bfd, &link_info, h, address, imppath, impfile, - impmember)) + impmember, syscall_flag)) einfo ("%X%s:%d: failed to import symbol %s: %E\n", filename, lineno, symname); }