From 666c12a0830e402db23004e20bb775af7bdbd14f Mon Sep 17 00:00:00 2001 From: Tim Abbott Date: Thu, 25 Sep 2008 15:01:55 -0400 Subject: [PATCH] Attach labels to spans. Signed-off-by: Tim Abbott --- objcommon.c | 27 +++++++++++++++++-------- objcommon.h | 3 +++ objmanip.c | 67 +++++++++++++++++++++++++++++++++++++++++++------------------ 3 files changed, 70 insertions(+), 27 deletions(-) diff --git a/objcommon.c b/objcommon.c index d523a80..9ea6575 100644 --- a/objcommon.c +++ b/objcommon.c @@ -342,18 +342,15 @@ static const char *find_caller(struct supersect *ss, asymbol *sym) return "*multiple_callers*"; } -asymbol **canonical_symbolp(struct superbfd *sbfd, asymbol *sym) +asymbol **symbolp_scan(struct superbfd *sbfd, asection *sect, bfd_vma value) { asymbol **csymp; asymbol **ret = NULL; for (csymp = sbfd->syms.data; csymp < sbfd->syms.data + sbfd->syms.size; csymp++) { asymbol *csymtemp = *csymp; - if (bfd_is_const_section(sym->section) && sym == csymtemp) - return csymp; if ((csymtemp->flags & BSF_DEBUGGING) != 0 || - sym->section != csymtemp->section || - sym->value != csymtemp->value) + sect != csymtemp->section || value != csymtemp->value) continue; if ((csymtemp->flags & BSF_GLOBAL) != 0) return csymp; @@ -365,9 +362,23 @@ asymbol **canonical_symbolp(struct superbfd *sbfd, asymbol *sym) /* For section symbols of sections containing no symbols, return the section symbol that relocations are generated against */ - if ((sym->flags & BSF_SECTION_SYM) != 0) - return &sym->section->symbol; - return ret; + if (value == 0) + return §->symbol; + return NULL; +} + +asymbol **canonical_symbolp(struct superbfd *sbfd, asymbol *sym) +{ + if (bfd_is_const_section(sym->section)) { + asymbol **csymp; + for (csymp = sbfd->syms.data; + csymp < sbfd->syms.data + sbfd->syms.size; csymp++) { + if (sym == *csymp) + return csymp; + } + return NULL; + } + return symbolp_scan(sbfd, sym->section, sym->value); } asymbol *canonical_symbol(struct superbfd *sbfd, asymbol *sym) diff --git a/objcommon.h b/objcommon.h index 5447363..f6671e8 100644 --- a/objcommon.h +++ b/objcommon.h @@ -161,6 +161,8 @@ DECLARE_VEC_TYPE(struct label_map, label_map_vec); struct span { struct supersect *ss; + asymbol *symbol; + const char *label; bfd_vma start; bfd_vma size; bool keep; @@ -238,6 +240,7 @@ char *str_pointer(struct supersect *ss, void *const *addr); #define read_num(ss, addr) ((typeof(*(addr))) \ read_reloc(ss, addr, sizeof(*(addr)), NULL)) +asymbol **symbolp_scan(struct superbfd *sbfd, asection *sect, bfd_vma value); asymbol *canonical_symbol(struct superbfd *sbfd, asymbol *sym); asymbol **canonical_symbolp(struct superbfd *sbfd, asymbol *sym); char *static_local_symbol(struct superbfd *sbfd, asymbol *sym); diff --git a/objmanip.c b/objmanip.c index eabef05..abb7860 100644 --- a/objmanip.c +++ b/objmanip.c @@ -1247,13 +1247,13 @@ void write_ksplice_symbol(struct supersect *ss, ".ksplice_symbols"); struct ksplice_symbol *ksymbol; unsigned long *ksymbol_offp; - const char *label = label_lookup(ss->parent, sym); + const char *label; char *output; if (span != NULL && span->start != 0) - assert(asprintf(&output, "%s%s", label, - (unsigned long)span->start, addstr_sect) >= 0); + label = span->label; else - assert(asprintf(&output, "%s%s", label, addstr_sect) >= 0); + label = label_lookup(ss->parent, sym); + assert(asprintf(&output, "%s%s", label, addstr_sect) >= 0); ksymbol_offp = ulong_hash_lookup(&ksplice_symbol_offset, output, FALSE); if (ksymbol_offp != NULL) { @@ -1264,6 +1264,16 @@ void write_ksplice_symbol(struct supersect *ss, ksymbol_offp = ulong_hash_lookup(&ksplice_symbol_offset, output, TRUE); *ksymbol_offp = addr_offset(ksymbol_ss, ksymbol); + write_reloc(ss, addr, &ksymbol_ss->symbol, *ksymbol_offp); + write_string(ksymbol_ss, &ksymbol->label, "%s", output); + + if (span != NULL && span->symbol == NULL) { + ksymbol->name = NULL; + return; + } + + write_ksplice_system_map(ksymbol_ss->parent, sym, addstr_sect); + if (bfd_is_und_section(sym->section) || (sym->flags & BSF_GLOBAL) != 0) { write_string(ksymbol_ss, &ksymbol->name, "%s", sym->name); } else if (bfd_is_const_section(sym->section)) { @@ -1277,12 +1287,6 @@ void write_ksplice_symbol(struct supersect *ss, write_string(ksymbol_ss, &ksymbol->name, "%s", gsym->name); } - - write_string(ksymbol_ss, &ksymbol->label, "%s", output); - - write_ksplice_system_map(ksymbol_ss->parent, sym, addstr_sect); - - write_reloc(ss, addr, &ksymbol_ss->symbol, *ksymbol_offp); } void write_ksplice_reloc(struct supersect *ss, arelent *orig_reloc) @@ -1299,6 +1303,8 @@ void write_ksplice_reloc(struct supersect *ss, arelent *orig_reloc) } struct span *span = reloc_target_span(ss, orig_reloc); + if (span == ss->spans.data && span->start != addend) + span = NULL; blot_section(ss, orig_reloc->address, howto); struct supersect *kreloc_ss = make_section(ss->parent, @@ -1338,7 +1344,7 @@ void blot_section(struct supersect *ss, int offset, reloc_howto_type *howto) void write_ksplice_section(struct superbfd *sbfd, asymbol **symp, struct span *span) { - asymbol *sym = *symp; + asymbol *sym = span->symbol == NULL ? *symp : span->symbol; struct supersect *ksect_ss = make_section(sbfd, ".ksplice_sections"); struct ksplice_section *ksect = sect_grow(ksect_ss, 1, struct ksplice_section); @@ -2120,19 +2126,42 @@ static void label_map_set(struct superbfd *sbfd, const char *oldlabel, DIE; } +static struct span *new_span(struct superbfd *sbfd, asection *sect, + bfd_vma start, bfd_vma size) +{ + struct supersect *ss = fetch_supersect(sbfd, sect); + struct span *span = vec_grow(&ss->spans, 1); + span->size = size; + span->start = start; + span->ss = ss; + span->keep = false; + span->shift = 0; + asymbol **symp = symbolp_scan(sbfd, sect, span->start); + if (symp != NULL) { + span->symbol = *symp; + span->label = label_lookup(sbfd, span->symbol); + } else { + span->symbol = NULL; + const char *label = label_lookup(sbfd, sect->symbol); + if (span->start != 0) { + char *buf; + assert(asprintf(&buf, "%s", label, + (unsigned long)span->start) >= 0); + span->label = buf; + } else { + span->label = label; + } + } + return span; +} + static void initialize_spans(struct superbfd *sbfd) { asection *sect; for (sect = sbfd->abfd->sections; sect != NULL; sect = sect->next) { struct supersect *ss = fetch_supersect(sbfd, sect); - if (ss->type == SS_TYPE_SPECIAL || ss->type == SS_TYPE_EXPORT) - continue; - struct span *span = vec_grow(&ss->spans, 1); - span->size = ss->contents.size; - span->start = 0; - span->ss = ss; - span->keep = false; - span->shift = 0; + if (ss->type != SS_TYPE_SPECIAL && ss->type != SS_TYPE_EXPORT) + new_span(sbfd, sect, 0, ss->contents.size); } } -- 2.11.4.GIT