From 4e94bf43a026f0bcef3e444adfbad6014493ce2d Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Tue, 1 Nov 2005 08:26:19 +0000 Subject: [PATCH] Fix the use of ELF type/size directives with local variables. * elf.h (elf_symtab_entry): Add in_table flag. (elf_sym_in_table): New. * elf.c (elf_symtab_entry_create): Initialize in_table to 0. (elf_symtab_append_entry, elf_symtab_insert_local_sym): Set flag to 1. * elf.c (elf_symtab_insert_local_sym): Don't create the entry here, instead take it as a parameter. * elf-objfmt.c (elf_objfmt_symtab_append): Only add if not in table by checking new in_table flag. (elf_objfmt_append_local_sym): Likewise, and pull some of the logic from the old elf_symtab_insert_local_sym function to do it. (elf_objfmt_directive): Don't append to ELF symbol table here, as we don't know yet if the variable is global or local. svn path=/trunk/yasm/; revision=1304 --- modules/objfmts/elf/elf-objfmt.c | 42 +- modules/objfmts/elf/elf.c | 29 +- modules/objfmts/elf/elf.h | 10 +- modules/objfmts/elf/tests/Makefile.inc | 3 + modules/objfmts/elf/tests/elftypesize.asm | 33 ++ modules/objfmts/elf/tests/elftypesize.errwarn | 0 modules/objfmts/elf/tests/elftypesize.hex | 552 ++++++++++++++++++ 7 files changed, 630 insertions(+), 39 deletions(-) create mode 100644 modules/objfmts/elf/tests/elftypesize.asm create mode 100644 modules/objfmts/elf/tests/elftypesize.errwarn create mode 100644 modules/objfmts/elf/tests/elftypesize.hex diff --git a/modules/objfmts/elf/elf-objfmt.c b/modules/objfmts/elf/elf-objfmt.c index 5b58df70..fa0604f7 100644 --- a/modules/objfmts/elf/elf-objfmt.c +++ b/modules/objfmts/elf/elf-objfmt.c @@ -93,16 +93,19 @@ elf_objfmt_symtab_append(yasm_objfmt_elf *objfmt_elf, yasm_symrec *sym, { /* Only append to table if not already appended */ elf_symtab_entry *entry = yasm_symrec_get_data(sym, &elf_symrec_data); - if (!entry) { - elf_strtab_entry *name = elf_strtab_append_str(objfmt_elf->strtab, - yasm_symrec_get_name(sym)); - entry = elf_symtab_entry_create(name, sym); + if (!entry || !elf_sym_in_table(entry)) { + if (!entry) { + elf_strtab_entry *name = + elf_strtab_append_str(objfmt_elf->strtab, + yasm_symrec_get_name(sym)); + entry = elf_symtab_entry_create(name, sym); + } elf_symtab_append_entry(objfmt_elf->elf_symtab, entry); + yasm_symrec_add_data(sym, &elf_symrec_data, entry); } elf_symtab_set_nonzero(entry, NULL, sectidx, bind, type, size, value); elf_sym_set_visibility(entry, vis); - yasm_symrec_add_data(sym, &elf_symrec_data, entry); return entry; } @@ -118,19 +121,26 @@ elf_objfmt_append_local_sym(yasm_symrec *sym, /*@null@*/ void *d) assert(info != NULL); - if (!yasm_symrec_get_data(sym, &elf_symrec_data)) { + if (!yasm_symrec_get_label(sym, &precbc)) + return 1; + sect = yasm_bc_get_section(precbc); + + entry = yasm_symrec_get_data(sym, &elf_symrec_data); + if (!entry || !elf_sym_in_table(entry)) { int is_sect = 0; - if (!yasm_symrec_get_label(sym, &precbc)) - return 1; - sect = yasm_bc_get_section(precbc); if (!yasm_section_is_absolute(sect) && strcmp(yasm_symrec_get_name(sym), yasm_section_get_name(sect))==0) is_sect = 1; /* neither sections nor locals (except when debugging) need names */ - entry = elf_symtab_insert_local_sym(info->objfmt_elf->elf_symtab, - info->local_names && !is_sect ? - info->objfmt_elf->strtab : NULL, sym); + if (!entry) { + elf_strtab_entry *name = info->local_names && !is_sect + ? elf_strtab_append_str(info->objfmt_elf->strtab, + yasm_symrec_get_name(sym)) + : NULL; + entry = elf_symtab_entry_create(name, sym); + } + elf_symtab_insert_local_sym(info->objfmt_elf->elf_symtab, entry); elf_symtab_set_nonzero(entry, sect, 0, STB_LOCAL, is_sect ? STT_SECTION : 0, NULL, 0); yasm_symrec_add_data(sym, &elf_symrec_data, entry); @@ -138,13 +148,7 @@ elf_objfmt_append_local_sym(yasm_symrec *sym, /*@null@*/ void *d) if (is_sect) return 1; } - else { - if (!yasm_symrec_get_label(sym, &precbc)) - return 1; - sect = yasm_bc_get_section(precbc); - } - entry = yasm_symrec_get_data(sym, &elf_symrec_data); if (precbc) value = precbc->offset + precbc->len; elf_symtab_set_nonzero(entry, sect, 0, 0, 0, NULL, value); @@ -1056,7 +1060,6 @@ elf_objfmt_directive(yasm_objfmt *objfmt, const char *name, if (!entry) { entry = elf_symtab_entry_create( elf_strtab_append_str(objfmt_elf->strtab, symname), sym); - elf_symtab_append_entry(objfmt_elf->elf_symtab, entry); yasm_symrec_add_data(sym, &elf_symrec_data, entry); } @@ -1081,7 +1084,6 @@ elf_objfmt_directive(yasm_objfmt *objfmt, const char *name, if (!entry) { entry = elf_symtab_entry_create( elf_strtab_append_str(objfmt_elf->strtab, symname), sym); - elf_symtab_append_entry(objfmt_elf->elf_symtab, entry); yasm_symrec_add_data(sym, &elf_symrec_data, entry); } diff --git a/modules/objfmts/elf/elf.c b/modules/objfmts/elf/elf.c index 36f6ccc8..7b0734f9 100644 --- a/modules/objfmts/elf/elf.c +++ b/modules/objfmts/elf/elf.c @@ -243,6 +243,7 @@ elf_symtab_entry_create(elf_strtab_entry *name, yasm_symrec *sym) { elf_symtab_entry *entry = yasm_xmalloc(sizeof(elf_symtab_entry)); + entry->in_table = 0; entry->sym = sym; entry->sect = NULL; entry->name = name; @@ -317,6 +318,7 @@ elf_symtab_create() elf_symtab_entry *entry = yasm_xmalloc(sizeof(elf_symtab_entry)); STAILQ_INIT(symtab); + entry->in_table = 1; entry->sym = NULL; entry->sect = NULL; entry->name = NULL; @@ -324,7 +326,7 @@ elf_symtab_create() entry->xsize = NULL; entry->size = 0; entry->index = SHN_UNDEF; - entry->bind = 0; + entry->bind = STB_LOCAL; entry->type = STT_NOTYPE; entry->vis = STV_DEFAULT; entry->symindex = 0; @@ -332,7 +334,7 @@ elf_symtab_create() return symtab; } -elf_symtab_entry * +void elf_symtab_append_entry(elf_symtab_head *symtab, elf_symtab_entry *entry) { if (symtab == NULL) @@ -343,18 +345,12 @@ elf_symtab_append_entry(elf_symtab_head *symtab, elf_symtab_entry *entry) yasm_internal_error(N_("symtab is missing initial dummy entry")); STAILQ_INSERT_TAIL(symtab, entry, qlink); - return entry; + entry->in_table = 1; } -elf_symtab_entry * -elf_symtab_insert_local_sym(elf_symtab_head *symtab, - elf_strtab_head *strtab, - yasm_symrec *sym) -{ - elf_strtab_entry *name = strtab - ? elf_strtab_append_str(strtab, yasm_symrec_get_name(sym)) - : NULL; - elf_symtab_entry *entry = elf_symtab_entry_create(name, sym); +void +elf_symtab_insert_local_sym(elf_symtab_head *symtab, elf_symtab_entry *entry) +{ elf_symtab_entry *after = STAILQ_FIRST(symtab); elf_symtab_entry *before = NULL; @@ -364,8 +360,7 @@ elf_symtab_insert_local_sym(elf_symtab_head *symtab, after = STAILQ_NEXT(after, qlink); } STAILQ_INSERT_AFTER(symtab, before, entry, qlink); - - return entry; + entry->in_table = 1; } void @@ -515,6 +510,12 @@ elf_sym_set_size(elf_symtab_entry *entry, entry->xsize = size; } +int +elf_sym_in_table(elf_symtab_entry *entry) +{ + return entry->in_table; +} + elf_secthead * elf_secthead_create(elf_strtab_entry *name, elf_section_type type, diff --git a/modules/objfmts/elf/elf.h b/modules/objfmts/elf/elf.h index 5a7fb159..bad69b7a 100644 --- a/modules/objfmts/elf/elf.h +++ b/modules/objfmts/elf/elf.h @@ -386,6 +386,7 @@ struct elf_strtab_entry { STAILQ_HEAD(elf_symtab_head, elf_symtab_entry); struct elf_symtab_entry { STAILQ_ENTRY(elf_symtab_entry) qlink; + int in_table; yasm_symrec *sym; yasm_section *sect; elf_strtab_entry *name; @@ -429,11 +430,9 @@ unsigned long elf_strtab_output_to_file(FILE *f, elf_strtab_head *head); elf_symtab_entry *elf_symtab_entry_create(elf_strtab_entry *name, struct yasm_symrec *sym); elf_symtab_head *elf_symtab_create(void); -elf_symtab_entry *elf_symtab_append_entry(elf_symtab_head *symtab, - elf_symtab_entry *entry); -elf_symtab_entry *elf_symtab_insert_local_sym(elf_symtab_head *symtab, - elf_strtab_head *strtab, - struct yasm_symrec *sym); +void elf_symtab_append_entry(elf_symtab_head *symtab, elf_symtab_entry *entry); +void elf_symtab_insert_local_sym(elf_symtab_head *symtab, + elf_symtab_entry *entry); void elf_symtab_destroy(elf_symtab_head *head); unsigned long elf_symtab_assign_indices(elf_symtab_head *symtab); unsigned long elf_symtab_write_to_file(FILE *f, elf_symtab_head *symtab); @@ -448,6 +447,7 @@ void elf_sym_set_visibility(elf_symtab_entry *entry, elf_symbol_vis vis); void elf_sym_set_type(elf_symtab_entry *entry, elf_symbol_type type); void elf_sym_set_size(elf_symtab_entry *entry, struct yasm_expr *size); +int elf_sym_in_table(elf_symtab_entry *entry); /* section header functions */ elf_secthead *elf_secthead_create(elf_strtab_entry *name, diff --git a/modules/objfmts/elf/tests/Makefile.inc b/modules/objfmts/elf/tests/Makefile.inc index f39c04a5..a20402bb 100644 --- a/modules/objfmts/elf/tests/Makefile.inc +++ b/modules/objfmts/elf/tests/Makefile.inc @@ -37,6 +37,9 @@ EXTRA_DIST += modules/objfmts/elf/tests/elfreloc-ext.hex EXTRA_DIST += modules/objfmts/elf/tests/elfabssect.asm EXTRA_DIST += modules/objfmts/elf/tests/elfabssect.errwarn EXTRA_DIST += modules/objfmts/elf/tests/elfabssect.hex +EXTRA_DIST += modules/objfmts/elf/tests/elftypesize.asm +EXTRA_DIST += modules/objfmts/elf/tests/elftypesize.errwarn +EXTRA_DIST += modules/objfmts/elf/tests/elftypesize.hex EXTRA_DIST += modules/objfmts/elf/tests/elfvisibility.asm EXTRA_DIST += modules/objfmts/elf/tests/elfvisibility.errwarn EXTRA_DIST += modules/objfmts/elf/tests/elfvisibility.hex diff --git a/modules/objfmts/elf/tests/elftypesize.asm b/modules/objfmts/elf/tests/elftypesize.asm new file mode 100644 index 00000000..88a72da8 --- /dev/null +++ b/modules/objfmts/elf/tests/elftypesize.asm @@ -0,0 +1,33 @@ +weak weaksym +weaksym: + +weaksym2: +weak weaksym2 + +global a +type a function +size a 500 +a: + +type b object +b: +global b + +type c function +c: + +global d +d: +type d object + +e: +global e +type e object + +f: +type f object + +g: +global g + +h: diff --git a/modules/objfmts/elf/tests/elftypesize.errwarn b/modules/objfmts/elf/tests/elftypesize.errwarn new file mode 100644 index 00000000..e69de29b diff --git a/modules/objfmts/elf/tests/elftypesize.hex b/modules/objfmts/elf/tests/elftypesize.hex new file mode 100644 index 00000000..c9f8d6e9 --- /dev/null +++ b/modules/objfmts/elf/tests/elftypesize.hex @@ -0,0 +1,552 @@ +7f +45 +4c +46 +01 +01 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +00 +03 +00 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +60 +01 +00 +00 +00 +00 +00 +00 +34 +00 +00 +00 +00 +00 +28 +00 +05 +00 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +2e +74 +65 +78 +74 +00 +2e +73 +74 +72 +74 +61 +62 +00 +2e +73 +79 +6d +74 +61 +62 +00 +2e +73 +68 +73 +74 +72 +74 +61 +62 +00 +00 +00 +00 +00 +2d +00 +77 +65 +61 +6b +73 +79 +6d +00 +77 +65 +61 +6b +73 +79 +6d +32 +00 +61 +00 +62 +00 +63 +00 +64 +00 +65 +00 +66 +00 +67 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +04 +00 +f1 +ff +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +04 +00 +1e +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +01 +00 +04 +00 +18 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +02 +00 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +03 +00 +04 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +20 +00 +04 +00 +0b +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +20 +00 +04 +00 +14 +00 +00 +00 +00 +00 +00 +00 +f4 +01 +00 +00 +12 +00 +04 +00 +16 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +11 +00 +04 +00 +1a +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +11 +00 +04 +00 +1c +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +11 +00 +04 +00 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +10 +00 +04 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +17 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +00 +21 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +07 +00 +00 +00 +03 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +64 +00 +00 +00 +22 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +0f +00 +00 +00 +02 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +88 +00 +00 +00 +d0 +00 +00 +00 +02 +00 +00 +00 +06 +00 +00 +00 +04 +00 +00 +00 +10 +00 +00 +00 +01 +00 +00 +00 +01 +00 +00 +00 +06 +00 +00 +00 +00 +00 +00 +00 +40 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +10 +00 +00 +00 +00 +00 +00 +00 -- 2.40.0