?? sunos.c
字號:
The address is put in the ld_symbols field. */ s = bfd_make_section (abfd, ".dynstr"); if (s == NULL || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) || ! bfd_set_section_alignment (abfd, s, 2)) return false; sunos_hash_table (info)->dynamic_sections_created = true; } if ((needed && ! sunos_hash_table (info)->dynamic_sections_needed) || info->shared) { bfd *dynobj; dynobj = sunos_hash_table (info)->dynobj; s = bfd_get_section_by_name (dynobj, ".got"); if (s->_raw_size == 0) s->_raw_size = BYTES_IN_WORD; sunos_hash_table (info)->dynamic_sections_needed = true; sunos_hash_table (info)->got_needed = true; } return true;}/* Add dynamic symbols during a link. This is called by the a.out backend linker for each object it encounters. */static booleansunos_add_dynamic_symbols (abfd, info, symsp, sym_countp, stringsp) bfd *abfd; struct bfd_link_info *info; struct external_nlist **symsp; bfd_size_type *sym_countp; char **stringsp;{ asection *s; bfd *dynobj; struct sunos_dynamic_info *dinfo; unsigned long need; /* Make sure we have all the required sections. */ if (info->hash->creator == abfd->xvec) { if (! sunos_create_dynamic_sections (abfd, info, (((abfd->flags & DYNAMIC) != 0 && ! info->relocateable) ? true : false))) return false; } /* There is nothing else to do for a normal object. */ if ((abfd->flags & DYNAMIC) == 0) return true; dynobj = sunos_hash_table (info)->dynobj; /* We do not want to include the sections in a dynamic object in the output file. We hack by simply clobbering the list of sections in the BFD. This could be handled more cleanly by, say, a new section flag; the existing SEC_NEVER_LOAD flag is not the one we want, because that one still implies that the section takes up space in the output file. If this is the first object we have seen, we must preserve the dynamic sections we just created. */ if (abfd != dynobj) abfd->sections = NULL; else { asection *s; for (s = abfd->sections; (s->flags & SEC_LINKER_CREATED) == 0; s = s->next) ; abfd->sections = s; } /* The native linker seems to just ignore dynamic objects when -r is used. */ if (info->relocateable) return true; /* There's no hope of using a dynamic object which does not exactly match the format of the output file. */ if (info->hash->creator != abfd->xvec) { bfd_set_error (bfd_error_invalid_operation); return false; } /* Make sure we have a .need and a .rules sections. These are only needed if there really is a dynamic object in the link, so they are not added by sunos_create_dynamic_sections. */ if (bfd_get_section_by_name (dynobj, ".need") == NULL) { /* The .need section holds the list of names of shared objets which must be included at runtime. The address of this section is put in the ld_need field. */ s = bfd_make_section (dynobj, ".need"); if (s == NULL || ! bfd_set_section_flags (dynobj, s, (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY)) || ! bfd_set_section_alignment (dynobj, s, 2)) return false; } if (bfd_get_section_by_name (dynobj, ".rules") == NULL) { /* The .rules section holds the path to search for shared objects. The address of this section is put in the ld_rules field. */ s = bfd_make_section (dynobj, ".rules"); if (s == NULL || ! bfd_set_section_flags (dynobj, s, (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_READONLY)) || ! bfd_set_section_alignment (dynobj, s, 2)) return false; } /* Pick up the dynamic symbols and return them to the caller. */ if (! sunos_slurp_dynamic_symtab (abfd)) return false; dinfo = (struct sunos_dynamic_info *) obj_aout_dynamic_info (abfd); *symsp = dinfo->dynsym; *sym_countp = dinfo->dynsym_count; *stringsp = dinfo->dynstr; /* Record information about any other objects needed by this one. */ need = dinfo->dyninfo.ld_need; while (need != 0) { bfd_byte buf[16]; unsigned long name, flags; unsigned short major_vno, minor_vno; struct bfd_link_needed_list *needed, **pp; char *namebuf, *p; size_t alc; bfd_byte b; char *namecopy; if (bfd_seek (abfd, need, SEEK_SET) != 0 || bfd_read (buf, 1, 16, abfd) != 16) return false; /* For the format of an ld_need entry, see aout/sun4.h. We should probably define structs for this manipulation. */ name = bfd_get_32 (abfd, buf); flags = bfd_get_32 (abfd, buf + 4); major_vno = (unsigned short)bfd_get_16 (abfd, buf + 8); minor_vno = (unsigned short)bfd_get_16 (abfd, buf + 10); need = bfd_get_32 (abfd, buf + 12); needed = ((struct bfd_link_needed_list *) bfd_alloc (abfd, sizeof (struct bfd_link_needed_list))); if (needed == NULL) return false; needed->by = abfd; /* We return the name as [-l]name[.maj][.min]. */ alc = 30; namebuf = (char *) bfd_malloc (alc + 1); if (namebuf == NULL) return false; p = namebuf; if ((flags & 0x80000000) != 0) { *p++ = '-'; *p++ = 'l'; } if (bfd_seek (abfd, name, SEEK_SET) != 0) { free (namebuf); return false; } do { if (bfd_read (&b, 1, 1, abfd) != 1) { free (namebuf); return false; } if ((size_t) (p - namebuf) >= alc) { char *n; alc *= 2; n = (char *) bfd_realloc (namebuf, alc + 1); if (n == NULL) { free (namebuf); return false; } p = n + (p - namebuf); namebuf = n; } *p++ = b; } while (b != '\0'); if (major_vno == 0) *p = '\0'; else { char majbuf[30]; char minbuf[30]; sprintf (majbuf, ".%d", major_vno); if (minor_vno == 0) minbuf[0] = '\0'; else sprintf (minbuf, ".%d", minor_vno); if ((p - namebuf) + strlen (majbuf) + strlen (minbuf) >= alc) { char *n; alc = (p - namebuf) + strlen (majbuf) + strlen (minbuf); n = (char *) bfd_realloc (namebuf, alc + 1); if (n == NULL) { free (namebuf); return false; } p = n + (p - namebuf); namebuf = n; } strcpy (p, majbuf); strcat (p, minbuf); } namecopy = bfd_alloc (abfd, strlen (namebuf) + 1); if (namecopy == NULL) { free (namebuf); return false; } strcpy (namecopy, namebuf); free (namebuf); needed->name = namecopy; needed->next = NULL; for (pp = &sunos_hash_table (info)->needed; *pp != NULL; pp = &(*pp)->next) ; *pp = needed; } return true;}/* Function to add a single symbol to the linker hash table. This is a wrapper around _bfd_generic_link_add_one_symbol which handles the tweaking needed for dynamic linking support. */static booleansunos_add_one_symbol (info, abfd, name, flags, section, value, string, copy, collect, hashp) struct bfd_link_info *info; bfd *abfd; const char *name; flagword flags; asection *section; bfd_vma value; const char *string; boolean copy; boolean collect; struct bfd_link_hash_entry **hashp;{ struct sunos_link_hash_entry *h; int new_flag; if ((flags & (BSF_INDIRECT | BSF_WARNING | BSF_CONSTRUCTOR)) != 0 || ! bfd_is_und_section (section)) h = sunos_link_hash_lookup (sunos_hash_table (info), name, true, copy, false); else h = ((struct sunos_link_hash_entry *) bfd_wrapped_link_hash_lookup (abfd, info, name, true, copy, false)); if (h == NULL) return false; if (hashp != NULL) *hashp = (struct bfd_link_hash_entry *) h; /* Treat a common symbol in a dynamic object as defined in the .bss section of the dynamic object. We don't want to allocate space for it in our process image. */ if ((abfd->flags & DYNAMIC) != 0 && bfd_is_com_section (section)) section = obj_bsssec (abfd); if (! bfd_is_und_section (section) && h->root.root.type != bfd_link_hash_new && h->root.root.type != bfd_link_hash_undefined && h->root.root.type != bfd_link_hash_defweak) { /* We are defining the symbol, and it is already defined. This is a potential multiple definition error. */ if ((abfd->flags & DYNAMIC) != 0) { /* The definition we are adding is from a dynamic object. We do not want this new definition to override the existing definition, so we pretend it is just a reference. */ section = bfd_und_section_ptr; } else if (h->root.root.type == bfd_link_hash_defined && h->root.root.u.def.section->owner != NULL && (h->root.root.u.def.section->owner->flags & DYNAMIC) != 0) { /* The existing definition is from a dynamic object. We want to override it with the definition we just found. Clobber the existing definition. */ h->root.root.type = bfd_link_hash_undefined; h->root.root.u.undef.abfd = h->root.root.u.def.section->owner; } else if (h->root.root.type == bfd_link_hash_common && (h->root.root.u.c.p->section->owner->flags & DYNAMIC) != 0) { /* The existing definition is from a dynamic object. We want to override it with the definition we just found. Clobber the existing definition. We can't set it to new, because it is on the undefined list. */ h->root.root.type = bfd_link_hash_undefined; h->root.root.u.undef.abfd = h->root.root.u.c.p->section->owner; } } if ((abfd->flags & DYNAMIC) != 0 && abfd->xvec == info->hash->creator && (h->flags & SUNOS_CONSTRUCTOR) != 0) { /* The existing symbol is a constructor symbol, and this symbol is from a dynamic object. A constructor symbol is actually a definition, although the type will be bfd_link_hash_undefined at this point. We want to ignore the definition from the dynamic object. */ section = bfd_und_section_ptr; } else if ((flags & BSF_CONSTRUCTOR) != 0 && (abfd->flags & DYNAMIC) == 0 && h->root.root.type == bfd_link_hash_defined && h->root.root.u.def.section->owner != NULL && (h->root.root.u.def.section->owner->flags & DYNAMIC) != 0) { /* The existing symbol is defined by a dynamic object, and this is a constructor symbol. As above, we want to force the use of the constructor symbol from the regular object. */ h->root.root.type = bfd_link_hash_new; } /* Do the usual procedure for adding a symbol. */ if (! _bfd_generic_link_add_one_symbol (info, abfd, name, flags, section, value, string, copy, collect, hashp)) return false; if (abfd->xvec == info->hash->creator) { /* Set a flag in the hash table entry indicating the type of reference or definition we just found. Keep a count of the number of dynamic symbols we find. A dynamic symbol is one which is referenced or defined by both a regular object and a shared object. */ if ((abfd->flags & DYNAMIC) == 0) { if (bfd_is_und_section (section)) new_flag = SUNOS_REF_REGULAR; else new_flag = SUNOS_DEF_REGULAR; } else { if (bfd_is_und_section (section)) new_flag = SUNOS_REF_DYNAMIC; else new_flag = SUNOS_DEF_DYNAMIC; } h->flags |= new_flag; if (h->dynindx == -1 && (h->flags & (SUNOS_DEF_REGULAR | SUNOS_REF_REGULAR)) != 0) { ++sunos_hash_table (info)->dynsymcount; h->dynindx = -2; } if ((flags & BSF_CONSTRUCTOR) != 0 && (abfd->flags & DYNAMIC) == 0) h->flags |= SUNOS_CONSTRUCTOR; } return true;}/* Return the list of objects needed by BFD. *//*ARGSUSED*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -