summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2006-06-10 06:33:00 +0000
committerUlrich Drepper <drepper@redhat.com>2006-06-10 06:33:00 +0000
commita688a732b671263838c2cd056ab5dbb71be91468 (patch)
treec0f222b2c1b7ae6d088d75f738350ba2e47b773b
parentbdb29c0b5613ecda012edfd291765f17da3939da (diff)
downloadelfutils-a688a732b671263838c2cd056ab5dbb71be91468.tar.gz
* i386_ld.c (elf_i386_finalize_plt): Don't change symbol table entries
for PLT entries if there is no local definition. * ld.c (parse_option): Handle -z ignore like --as-needed and -z record like --no-as-needed. * ld.h (struct ld_state): Remove ignore_unused_dsos field. * ldgeneric.c (new_generated_scn): Always compute ndt_needed by looping over DSOs. When deciding about adding DT_NEEDED entries use ->as_needed instead of ignore_unused_dsos.
-rw-r--r--libdw/libdw.h1
-rw-r--r--libelf/libelfP.h17
-rw-r--r--src/ChangeLog17
-rw-r--r--src/addr2line.c3
-rw-r--r--src/i386_ld.c21
-rw-r--r--src/ld.c4
-rw-r--r--src/ld.h4
-rw-r--r--src/ldgeneric.c72
8 files changed, 74 insertions, 65 deletions
diff --git a/libdw/libdw.h b/libdw/libdw.h
index 0758a38d..424c354e 100644
--- a/libdw/libdw.h
+++ b/libdw/libdw.h
@@ -1,6 +1,7 @@
/* Interfaces for libdw.
Copyright (C) 2002, 2004, 2005, 2006 Red Hat, Inc.
This file is part of Red Hat elfutils.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
Red Hat elfutils is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by the
diff --git a/libelf/libelfP.h b/libelf/libelfP.h
index 54158aeb..ed6b5f7f 100644
--- a/libelf/libelfP.h
+++ b/libelf/libelfP.h
@@ -1,5 +1,5 @@
/* Internal interfaces for libelf.
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006 Red Hat, Inc.
+ Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 Red Hat, Inc.
This file is part of Red Hat elfutils.
Contributed by Ulrich Drepper <drepper@redhat.com>, 1998.
@@ -546,8 +546,9 @@ extern uint32_t __libelf_crc32 (uint32_t crc, unsigned char *buf, size_t len)
/* We often have to update a flag iff a value changed. Make this
- convenient. */
-#define update_if_changed(var, exp, flag) \
+ convenient. None of the parameters must have a side effect. */
+#ifdef __GNUC__
+# define update_if_changed(var, exp, flag) \
do { \
__typeof__ (var) *_var = &(var); \
__typeof__ (exp) _exp = (exp); \
@@ -557,5 +558,15 @@ extern uint32_t __libelf_crc32 (uint32_t crc, unsigned char *buf, size_t len)
(flag) |= ELF_F_DIRTY; \
} \
} while (0)
+#else
+# define update_if_changed(var, exp, flag) \
+ do { \
+ if ((var) != (exp)) \
+ { \
+ (var) = (exp); \
+ (flag) |= ELF_F_DIRTY; \
+ } \
+ } while (0)
+#endif
#endif /* libelfP.h */
diff --git a/src/ChangeLog b/src/ChangeLog
index 70ab5457..8ed1b34f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,15 @@
+2006-06-09 Ulrich Drepper <drepper@redhat.com>
+
+ * i386_ld.c (elf_i386_finalize_plt): Don't change symbol table entries
+ for PLT entries if there is no local definition.
+
+ * ld.c (parse_option): Handle -z ignore like --as-needed and
+ -z record like --no-as-needed.
+ * ld.h (struct ld_state): Remove ignore_unused_dsos field.
+ * ldgeneric.c (new_generated_scn): Always compute ndt_needed by
+ looping over DSOs. When deciding about adding DT_NEEDED entries
+ use ->as_needed instead of ignore_unused_dsos.
+
2006-05-31 Ulrich Drepper <drepper@redhat.com>
* ld.c: Recognize --as-needed and --no-as-needed options.
@@ -9,11 +21,6 @@
combinations.
(mark_as_needed): Fix loop.
-2006-05-28 Ulrich Drepper <drepper@redhat.com>
-
- * addr2line.c (print_dwarf_function): Use unsigned type for lineno
- and colno.
-
2006-05-27 Ulrich Drepper <drepper@redhat.com>
* readelf.c (handle_relocs_rela): Better notations for addon value.
diff --git a/src/addr2line.c b/src/addr2line.c
index 1729058e..bc0ea803 100644
--- a/src/addr2line.c
+++ b/src/addr2line.c
@@ -258,8 +258,7 @@ print_dwarf_function (Dwfl_Module *mod, Dwarf_Addr addr)
&attr_mem), &val) == 0)
{
const char *file = dwarf_filesrc (files, val, NULL, NULL);
- unsigned int lineno = 0;
- unsigned int colno = 0;
+ int lineno = 0, colno = 0;
if (dwarf_formudata (dwarf_attr (&scopes[i],
DW_AT_call_line,
&attr_mem), &val) == 0)
diff --git a/src/i386_ld.c b/src/i386_ld.c
index 1724d324..d1a213d6 100644
--- a/src/i386_ld.c
+++ b/src/i386_ld.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
+/* Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
This file is part of Red Hat elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2001.
@@ -396,14 +396,19 @@ elf_i386_finalize_plt (struct ld_state *statep, size_t nsym,
/* Point the GOT entry at the PLT entry, after the initial jmp. */
((Elf32_Word *) data->d_buf)[3 + cnt] = pltentryaddr + 6;
- /* The value of the symbol is the address of the corresponding PLT
- entry. Store the address, also for the normal symbol table if
- this is necessary. */
- ((Elf32_Sym *) dynsymdata->d_buf)[1 + cnt].st_value = pltentryaddr;
- if (symdata != NULL)
- ((Elf32_Sym *) symdata->d_buf)[nsym - statep->nplt + cnt].st_value
- = pltentryaddr;
+ /* If the symbol is defined, adjust the address. */
+ if (((Elf32_Sym *) dynsymdata->d_buf)[1 + cnt].st_shndx != SHN_UNDEF)
+ {
+ /* The value of the symbol is the address of the corresponding PLT
+ entry. Store the address, also for the normal symbol table if
+ this is necessary. */
+ ((Elf32_Sym *) dynsymdata->d_buf)[1 + cnt].st_value = pltentryaddr;
+
+ if (symdata != NULL)
+ ((Elf32_Sym *) symdata->d_buf)[nsym - statep->nplt + cnt].st_value
+ = pltentryaddr;
+ }
}
/* Create the .plt section. */
diff --git a/src/ld.c b/src/ld.c
index 99190df9..53386569 100644
--- a/src/ld.c
+++ b/src/ld.c
@@ -926,9 +926,9 @@ parse_z_option (const char *arg)
&& ld_state.file_type == dso_file_type)
ld_state.dt_flags_1 |= DF_1_NOOPEN;
else if (strcmp (arg, "ignore") == 0)
- ld_state.ignore_unused_dsos = true;
+ ld_state.as_needed = true;
else if (strcmp (arg, "record") == 0)
- ld_state.ignore_unused_dsos = false;
+ ld_state.as_needed = false;
else if (strcmp (arg, "systemlibrary") == 0)
ld_state.is_system_library = true;
else if (strcmp (arg, "allextract") != 0
diff --git a/src/ld.h b/src/ld.h
index 47354cbe..6e8e7b5f 100644
--- a/src/ld.h
+++ b/src/ld.h
@@ -999,10 +999,6 @@ struct ld_state
/* Lazy-loading state for dependencies. */
bool lazyload;
- /* True is DSOs which are not used in the linking process are not
- recorded. */
- bool ignore_unused_dsos;
-
/* True if in executables all global symbols should be exported in
the dynamic symbol table. */
diff --git a/src/ldgeneric.c b/src/ldgeneric.c
index e0621d01..6cad1ac7 100644
--- a/src/ldgeneric.c
+++ b/src/ldgeneric.c
@@ -2264,7 +2264,6 @@ ld_generic_generate_sections (struct ld_state *statep)
program header. */
if (dynamically_linked_p ())
{
- int ndt_needed;
/* Use any versioning (defined or required)? */
bool use_versioning = false;
/* Use version requirements? */
@@ -2295,11 +2294,6 @@ ld_generic_generate_sections (struct ld_state *statep)
new_generated_scn (scn_dot_hash, ".hash", SHT_HASH, SHF_ALLOC,
sizeof (Elf32_Word), sizeof (Elf32_Word));
- /* By default we add all DSOs provided on the command line. If
- the user added '-z ignore' to the command line we only add
- those which are actually used. */
- ndt_needed = ld_state.ignore_unused_dsos ? 0 : ld_state.ndsofiles;
-
/* Create the section associated with the PLT if necessary. */
if (ld_state.nplt > 0)
{
@@ -2374,29 +2368,29 @@ ld_generic_generate_sections (struct ld_state *statep)
new_generated_scn (scn_dot_version_r, ".gnu.version_r",
SHT_GNU_verneed, SHF_ALLOC, 0,
xelf_fsize (ld_state.outelf, ELF_T_WORD, 1));
+ }
- /* Now count the used DSOs since this is what the user
- wants. */
- ndt_needed = 0;
- if (ld_state.ndsofiles > 0)
- {
- struct usedfiles *frunp = ld_state.dsofiles;
+ /* Now count the used DSOs since this is what the user
+ wants. */
+ int ndt_needed = 0;
+ if (ld_state.ndsofiles > 0)
+ {
+ struct usedfiles *frunp = ld_state.dsofiles;
- do
- if (! ld_state.ignore_unused_dsos || frunp->used)
- {
- ++ndt_needed;
- if (frunp->lazyload)
- /* We have to create another dynamic section
- entry for the DT_POSFLAG_1 entry.
-
- XXX Once more functionality than the
- lazyloading flag are suppported the test
- must be extended. */
- ++ndt_needed;
- }
- while ((frunp = frunp->next) != ld_state.dsofiles);
- }
+ do
+ if (! frunp->as_needed || frunp->used)
+ {
+ ++ndt_needed;
+ if (frunp->lazyload)
+ /* We have to create another dynamic section
+ entry for the DT_POSFLAG_1 entry.
+
+ XXX Once more functionality than the lazyloading
+ flag are suppported the test must be
+ extended. */
+ ++ndt_needed;
+ }
+ while ((frunp = frunp->next) != ld_state.dsofiles);
}
if (use_versioning)
@@ -3923,7 +3917,7 @@ ld_generic_create_outfile (struct ld_state *statep)
struct usedfiles *frunp = ld_state.dsofiles;
do
- if (! ld_state.ignore_unused_dsos || frunp->used)
+ if (! frunp->as_needed || frunp->used)
frunp->sonameent = ebl_strtabadd (dynstrtab, frunp->soname,
0);
while ((frunp = frunp->next) != ld_state.dsofiles);
@@ -5283,7 +5277,6 @@ cannot create hash table section for output file: %s"),
if (symstrent[cnt] != NULL)
{
XElf_Sym_vardef (sym);
- size_t hashidx;
size_t dynidx = ndxtosym[cnt]->outdynsymidx;
#if NATIVE_ELF != 0
@@ -5301,7 +5294,7 @@ cannot create hash table section for output file: %s"),
(void) xelf_update_sym (dynsymdata, dynidx, sym);
/* Add to the hash table. */
- hashidx = hashcodes[dynidx] % nbucket;
+ size_t hashidx = hashcodes[dynidx] % nbucket;
if (bucket[hashidx] == 0)
bucket[hashidx] = dynidx;
else
@@ -5428,7 +5421,7 @@ cannot create hash table section for output file: %s"),
strtab_ent = ebl_strtabadd (ld_state.shstrtab, ".strtab", 8);
/* At this point we would have to test for failures in the
allocation. But we skip this. First, the problem will be caught
- latter when doing more allocations for the section header table.
+ later when doing more allocations for the section header table.
Even if this would not be the case all that would happen is that
the section names are empty. The binary would still be usable if
it is an executable or a DSO. Not adding the test here saves
@@ -5533,11 +5526,7 @@ cannot create hash table section for output file: %s"),
groups = ld_state.groups;
while (groups != NULL)
{
- Elf_Scn *scn;
- struct scngroup *oldp;
- Elf32_Word si;
-
- scn = elf_getscn (ld_state.outelf, groups->outscnidx);
+ Elf_Scn *scn = elf_getscn (ld_state.outelf, groups->outscnidx);
xelf_getshdr (scn, shdr);
assert (shdr != NULL);
@@ -5548,7 +5537,8 @@ cannot create hash table section for output file: %s"),
shdr->sh_entsize = sizeof (Elf32_Word);
/* Determine the index for the signature symbol. */
- si = groups->symbol->file->symindirect[groups->symbol->symidx];
+ Elf32_Word si
+ = groups->symbol->file->symindirect[groups->symbol->symidx];
if (si == 0)
{
assert (groups->symbol->file->symref[groups->symbol->symidx]
@@ -5560,7 +5550,7 @@ cannot create hash table section for output file: %s"),
(void) xelf_update_shdr (scn, shdr);
- oldp = groups;
+ struct scngroup *oldp = groups;
groups = groups->next;
free (oldp);
}
@@ -5794,8 +5784,8 @@ internal error: nobits section follows nobits section"));
(void) xelf_update_phdr (ld_state.outelf, 0, phdr);
- /* Adjust the addresses in the addresses of the symbol according
- to the load addresses of the sections. */
+ /* Adjust the addresses in the address fields of the symbol
+ records according to the load addresses of the sections. */
if (ld_state.need_symtab)
for (cnt = 1; cnt < nsym; ++cnt)
{
@@ -5948,7 +5938,7 @@ internal error: nobits section follows nobits section"));
struct usedfiles *runp = ld_state.dsofiles->next;
do
- if (! ld_state.ignore_unused_dsos || runp->used)
+ if (runp->used || !runp->as_needed)
{
/* Add the position-dependent flag if necessary. */
if (runp->lazyload)