Search
j0ke.net Open Build Service
>
Projects
>
devel
>
binutils
> suse-bdirect.diff
Sign Up
|
Log In
Username
Password
Cancel
Overview
Repositories
Revisions
Requests
Users
Advanced
Attributes
Meta
File suse-bdirect.diff of Package binutils
This patch omits the DT_SUSE_DIRECT define and hence depends ================================================================================ --- binutils-2.17.50.0.4/bfd/elf-bfd.h +++ binutils-2.17.50.0.4/bfd/elf-bfd.h @@ -172,6 +172,14 @@ matters. */ unsigned int pointer_equality_needed : 1; + /* FIXME: these 2 bits consume another 4 bytes. */ + /* Symbol is concrete, ie. non-vague if we can detect that, from the + .direct section. */ + unsigned int concrete_ref : 1; + /* Symbol is certainly vague (if we can detect that), from the + .direct section. */ + unsigned int vague_ref : 1; + /* String table index in .dynstr if this is a dynamic symbol. */ unsigned long dynstr_index; @@ -403,6 +411,9 @@ asection *tls_sec; bfd_size_type tls_size; + /* Direct linkage output section. */ + asection *direct_sec; + /* A linked list of BFD's loaded in the link. */ struct elf_link_loaded_list *loaded; @@ -1323,6 +1334,7 @@ name actually used, which will be the DT_SONAME entry if there is one. */ const char *dt_name; + int dt_needed_idx; /* Records the result of `get_program_header_size'. */ bfd_size_type program_header_size; @@ -1426,6 +1438,7 @@ #define elf_local_got_offsets(bfd) (elf_tdata(bfd) -> local_got.offsets) #define elf_local_got_ents(bfd) (elf_tdata(bfd) -> local_got.ents) #define elf_dt_name(bfd) (elf_tdata(bfd) -> dt_name) +#define elf_dt_needed_idx(bfd) (elf_tdata(bfd) -> dt_needed_idx) #define elf_dyn_lib_class(bfd) (elf_tdata(bfd) -> dyn_lib_class) #define elf_bad_symtab(bfd) (elf_tdata(bfd) -> bad_symtab) #define elf_flags_init(bfd) (elf_tdata(bfd) -> flags_init) --- binutils-2.17.50.0.4/bfd/elf.c +++ binutils-2.17.50.0.4/bfd/elf.c @@ -1256,6 +1256,7 @@ case DT_RELCOUNT: name = "RELCOUNT"; break; case DT_FLAGS_1: name = "FLAGS_1"; break; case DT_VERSYM: name = "VERSYM"; break; + case DT_SUSE_DIRECT: name = "SUSE_DIRECT"; break; case DT_VERDEF: name = "VERDEF"; break; case DT_VERDEFNUM: name = "VERDEFNUM"; break; case DT_VERNEED: name = "VERNEED"; break; @@ -1612,6 +1613,7 @@ table->runpath = NULL; table->tls_sec = NULL; table->tls_size = 0; + table->direct_sec = NULL; table->loaded = NULL; table->is_relocatable_executable = FALSE; --- binutils-2.17.50.0.4/bfd/elflink.c +++ binutils-2.17.50.0.4/bfd/elflink.c @@ -195,6 +195,16 @@ elf_hash_table (info)->eh_info.hdr_sec = s; } + if (info->direct && !info->executable) + { + s = bfd_make_section (abfd, ".suse.direct"); + if (s == NULL + || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) + || ! bfd_set_section_alignment (abfd, s, 2)) + return FALSE; + elf_hash_table (info)->direct_sec = s; + } + /* Create sections to hold version informations. These are removed if they are not needed. */ s = bfd_make_section_with_flags (abfd, ".gnu.version_d", @@ -2959,6 +2969,7 @@ if (!_bfd_elf_add_dynamic_entry (info, DT_NEEDED, strindex)) return -1; + elf_dt_needed_idx (abfd) = ++(info->dt_needed_index); } else /* We were just checking for existence of the tag. */ @@ -3166,10 +3177,15 @@ long old_dynsymcount = 0; size_t tabsize = 0; size_t hashsize = 0; + asection *direct_sec; + unsigned char *direct_data; htab = elf_hash_table (info); bed = get_elf_backend_data (abfd); + direct_sec = NULL; + direct_data = NULL; + if ((abfd->flags & DYNAMIC) == 0) dynamic = FALSE; else @@ -3189,6 +3205,16 @@ bfd_set_error (bfd_error_wrong_format); goto error_return; } + if (info->direct) + direct_sec = bfd_get_section_by_name (abfd, ".suse.direct"); + if (direct_sec != NULL) + { + direct_data = bfd_alloc (abfd, direct_sec->size); + if (direct_data == NULL + || ! bfd_get_section_contents (abfd, direct_sec, + direct_data, 0, direct_sec->size)) + goto error_return; + } } /* As a GNU extension, any input sections which are named @@ -3907,6 +3933,22 @@ && vernum > 1 && definition) h->verinfo.verdef = &elf_tdata (abfd)->verdef[vernum - 1]; + + if (direct_sec != NULL) + { + unsigned long d_idx = isym - isymbuf; + unsigned long direct_entry; + d_idx += extsymoff; + d_idx *= 2; + BFD_ASSERT (d_idx <= bfd_get_section_size (direct_sec)); + direct_entry = bfd_get_16 (abfd, direct_data + d_idx); + if ((direct_entry & DT_SUSE_DIRECT_VAGUE) != 0) + h->vague_ref = 1; + if (!h->vague_ref + && ((direct_entry & DT_SUSE_DIRECT_MASK) + != DT_SUSE_DIRECT_UNKNOWN)) + h->concrete_ref = 1; + } } if (! (_bfd_generic_link_add_one_symbol @@ -4597,6 +4639,8 @@ if (isymbuf != NULL) free (isymbuf); error_return: + if (direct_data != NULL) + free (direct_data); return FALSE; } @@ -5963,6 +6007,24 @@ return FALSE; } + /* Create the direct bindings section - 1 entry per dynsym. */ + s = bfd_get_section_by_name (dynobj, ".suse.direct"); + if (s != NULL) + { + if (dynsymcount == 0) + s->flags |= SEC_EXCLUDE; + else + { + s->size = dynsymcount * sizeof (Elf_External_Direct); + s->contents = bfd_zalloc (output_bfd, s->size); + if (s->contents == NULL) + return FALSE; + memset (s->contents, 0xff, s->size); + if (!_bfd_elf_add_dynamic_entry (info, DT_SUSE_DIRECT, 0)) + return FALSE; + } + } + /* Set the size of the .dynsym and .hash sections. We counted the number of dynamic symbols in elf_link_add_object_symbols. We will build the contents of .dynsym and .hash when we build @@ -6229,6 +6291,8 @@ asection *hash_sec; /* symbol version section (.gnu.version). */ asection *symver_sec; + /* .direct linkage section. */ + asection *direct_sec; /* Buffer large enough to hold contents of any section. */ bfd_byte *contents; /* Buffer large enough to hold external relocs of any section. */ @@ -7123,6 +7187,43 @@ eversym += h->dynindx; _bfd_elf_swap_versym_out (finfo->output_bfd, &iversym, eversym); } + + if (finfo->direct_sec != NULL) + { + int dt_index = DT_SUSE_DIRECT_UNKNOWN; + bfd_vma offset = 2 * h->dynindx; + BFD_ASSERT (offset <= finfo->direct_sec->size); + + if ((h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + && h->root.u.def.section != NULL + && h->root.u.def.section->owner != NULL) + { + asection *sec = h->root.u.def.section; + + dt_index = elf_dt_needed_idx (sec->owner); + + if ((sec->owner->flags & DYNAMIC) == 0) + { + if (sec->name == NULL + || strncmp (sec->name, ".gnu.linkonce", + strlen (".gnu.linkonce")) == 0) + dt_index |= DT_SUSE_DIRECT_VAGUE; + /* app -> library data references get turned into copy + relocs, so objects can migrate unpredictably into the + application itself. */ + else if (h->type == STT_OBJECT) + dt_index |= DT_SUSE_DIRECT_VAGUE; + } + else if (h->vague_ref) + dt_index |= DT_SUSE_DIRECT_VAGUE; + else if (!h->concrete_ref) + dt_index = DT_SUSE_DIRECT_UNKNOWN; + } + bfd_put_16 (finfo->output_bfd, + dt_index, + finfo->direct_sec->contents + offset); + } } /* If we're stripping it, then it was just a dynamic symbol, and @@ -8273,12 +8374,14 @@ if (! dynamic) { + finfo.direct_sec = NULL; finfo.dynsym_sec = NULL; finfo.hash_sec = NULL; finfo.symver_sec = NULL; } else { + finfo.direct_sec = bfd_get_section_by_name (dynobj, ".suse.direct"); finfo.dynsym_sec = bfd_get_section_by_name (dynobj, ".dynsym"); finfo.hash_sec = bfd_get_section_by_name (dynobj, ".hash"); BFD_ASSERT (finfo.dynsym_sec != NULL); @@ -9067,6 +9170,9 @@ case DT_VERNEED: name = ".gnu.version_r"; goto get_vma; + case DT_SUSE_DIRECT: + name = ".suse.direct"; + goto get_vma; case DT_VERSYM: name = ".gnu.version"; get_vma: --- binutils-2.17.50.0.4/binutils/readelf.c +++ binutils-2.17.50.0.4/binutils/readelf.c @@ -147,6 +147,7 @@ static int do_dynamic; static int do_syms; static int do_reloc; +static int do_direct; static int do_sections; static int do_section_groups; static int do_section_details; @@ -1514,6 +1515,7 @@ case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */ case DT_VERSYM: return "VERSYM"; + case DT_SUSE_DIRECT: return "SUSE_DIRECT"; case DT_TLSDESC_GOT: return "TLSDESC_GOT"; case DT_TLSDESC_PLT: return "TLSDESC_PLT"; @@ -2682,6 +2684,7 @@ {"symbols", no_argument, 0, 's'}, {"syms", no_argument, 0, 's'}, {"relocs", no_argument, 0, 'r'}, + {"direct", no_argument, 0, 'y'}, {"notes", no_argument, 0, 'n'}, {"dynamic", no_argument, 0, 'd'}, {"arch-specific", no_argument, 0, 'A'}, @@ -2719,6 +2722,7 @@ --symbols An alias for --syms\n\ -n --notes Display the core notes (if present)\n\ -r --relocs Display the relocations (if present)\n\ + -y --direct Display direct linkage table (if present)\n\ -u --unwind Display the unwind info (if present)\n\ -d --dynamic Display the dynamic section (if present)\n\ -V --version-info Display the version sections (if present)\n\ @@ -2808,7 +2812,7 @@ usage (); while ((c = getopt_long - (argc, argv, "ersuahnldSDAINtgw::x:i:vVWH", options, NULL)) != EOF) + (argc, argv, "erysuahnldSDAINtgw::x:i:vVWH", options, NULL)) != EOF) { char *cp; int section; @@ -2825,6 +2829,7 @@ case 'a': do_syms++; do_reloc++; + do_direct++; do_unwind++; do_dynamic++; do_header++; @@ -2858,6 +2863,9 @@ case 'r': do_reloc++; break; + case 'y': + do_direct++; + break; case 'u': do_unwind++; break; @@ -3067,7 +3075,7 @@ if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections && !do_segments && !do_header && !do_dump && !do_version && !do_histogram && !do_debugging && !do_arch && !do_notes - && !do_section_groups) + && !do_section_groups && !do_direct) usage (); else if (argc < 3) { @@ -4722,6 +4730,131 @@ return 1; } +static void +print_dt_needed_name (int idx) +{ + const char *name = NULL; + Elf_Internal_Dyn *entry; + + idx &= DT_SUSE_DIRECT_MASK; + + switch (idx) + { + case 0: + name = _("<self>"); + break; + case DT_SUSE_DIRECT_UNKNOWN: + name = _("<unknown>"); + break; + default: + idx--; + + for (entry = dynamic_section; + entry < dynamic_section + dynamic_nent && idx > 0; + entry++) + if (entry->d_tag == DT_NEEDED) + idx--; + + if (idx == 0) + { + if (VALID_DYNAMIC_NAME (entry->d_un.d_val)) + name = GET_DYNAMIC_NAME (entry->d_un.d_val); + else + name = NULL; + } + break; + } + + if (!name) + name = _("<out-of-range>"); + if (do_wide) + printf ("%s", name); + else + printf ("%-25s", name); +} + +static int +process_direct (FILE *file) +{ + unsigned int i; + unsigned int si; + char *strtab; + unsigned char *directtab; + Elf_Internal_Sym *symtab = NULL; + Elf_Internal_Sym *psym; + Elf_Internal_Shdr *direct = NULL; + Elf_Internal_Shdr *dynsym = NULL; + Elf_Internal_Shdr *section; + + if (!do_direct) + return 1; + if (!dynamic_symbols || !dynamic_section || !dynamic_strings) + return 1; + + for (i = 0, section = section_headers; + i < elf_header.e_shnum; + i++, section++) + { + if (section->sh_type == SHT_DYNSYM) + dynsym = section; + if (!strcmp (SECTION_NAME (section), ".suse.direct")) + direct = section; + } + if (!dynsym || !direct) + return 1; + + symtab = GET_ELF_SYMBOLS (file, dynsym); + if (!symtab) + return 1; + + directtab = get_data (NULL, file, direct->sh_offset, + direct->sh_size, 1, _("direct linkage table")); + if (!symtab) + { + free (symtab); + return 1; + } + + if (dynsym->sh_link == elf_header.e_shstrndx) + strtab = string_table; + else + { + Elf_Internal_Shdr *string_sec; + + string_sec = SECTION_HEADER (dynsym->sh_link); + + strtab = get_data (NULL, file, string_sec->sh_offset, + string_sec->sh_size, 1, _("string table")); + } + + assert (strtab != NULL); + + printf (_("\nDirect relocations for image:\n")); + printf (_(" Num: Index Vague Binding Symbol\n")); + for (si = 0, psym = symtab; + si < dynsym->sh_size / dynsym->sh_entsize; + si++, psym++) + { + unsigned int field; + printf ("%6d: ", si); + field = byte_get (directtab + (si * 2), 2); + printf ("[0x%.4x] ", field); + printf ("%s", (field & DT_SUSE_DIRECT_VAGUE) ? "Vague" : " "); + printf (" "); + print_dt_needed_name (field); + printf (" "); + print_symbol (25, strtab + psym->st_name); + printf ("\n"); + } + + free (symtab); + if (strtab != string_table) + free (strtab); + + return 1; +} + + /* Process the unwind section. */ #include "unwind-ia64.h" @@ -9236,6 +9369,8 @@ process_relocs (file); + process_direct (file); + process_unwind (file); process_symbol_table (file); --- binutils-2.17.50.0.4/include/bfdlink.h +++ binutils-2.17.50.0.4/include/bfdlink.h @@ -246,6 +246,9 @@ /* TRUE if BFD should pre-bind symbols in a shared object. */ unsigned int symbolic: 1; + /* TRUE if BFD should bind symbols directly to resolved at link time. */ + unsigned int direct: 1; + /* TRUE if BFD should export all symbols in the dynamic symbol table of an executable, rather than only those used. */ unsigned int export_dynamic: 1; @@ -441,6 +444,9 @@ /* List of symbols should be dynamic. */ struct bfd_elf_dynamic_list *dynamic; + + /* current max dtinfo section number. */ + int dt_needed_index; }; /* This structures holds a set of callback functions. These are --- binutils-2.17.50.0.4/include/elf/common.h +++ binutils-2.17.50.0.4/include/elf/common.h @@ -651,6 +651,11 @@ #define DF_BIND_NOW (1 << 3) #define DF_STATIC_TLS (1 << 4) +/* Constants for the DT_DIRECT entries. */ +#define DT_SUSE_DIRECT_VAGUE (1<<15) +#define DT_SUSE_DIRECT_MASK 0xfff +#define DT_SUSE_DIRECT_UNKNOWN DT_SUSE_DIRECT_MASK + /* These constants are used for the version number of a Elf32_Verdef structure. */ --- binutils-2.17.50.0.4/include/elf/external.h +++ binutils-2.17.50.0.4/include/elf/external.h @@ -213,6 +213,10 @@ unsigned char vd_next[4]; } Elf_External_Verdef; +typedef struct { + unsigned char dir_libidx[2]; +} Elf_External_Direct; + /* This structure appears in a SHT_GNU_verdef section. */ typedef struct { --- binutils-2.17.50.0.4/ld/lexsup.c +++ binutils-2.17.50.0.4/ld/lexsup.c @@ -71,6 +71,7 @@ OPTION_CREF, OPTION_DEFSYM, OPTION_DEMANGLE, + OPTION_DIRECT, OPTION_DYNAMIC_LINKER, OPTION_SYSROOT, OPTION_EB, @@ -346,6 +347,8 @@ '\0', NULL, NULL, ONE_DASH }, { {"Bsymbolic", no_argument, NULL, OPTION_SYMBOLIC}, '\0', NULL, N_("Bind global references locally"), ONE_DASH }, + { {"Bdirect", no_argument, NULL, OPTION_DIRECT}, + '\0', NULL, N_("Direct-linkage the the shared libraries"), ONE_DASH }, { {"check-sections", no_argument, NULL, OPTION_CHECK_SECTIONS}, '\0', NULL, N_("Check section addresses for overlaps (default)"), TWO_DASHES }, @@ -761,6 +764,9 @@ cplus_demangle_set_style (style); } break; + case OPTION_DIRECT: + link_info.direct = TRUE; + break; case 'I': /* Used on Solaris. */ case OPTION_DYNAMIC_LINKER: command_line.interpreter = optarg;