]> granicus.if.org Git - yasm/commitdiff
Fix the use of ELF type/size directives with local variables.
authorPeter Johnson <peter@tortall.net>
Tue, 1 Nov 2005 08:26:19 +0000 (08:26 -0000)
committerPeter Johnson <peter@tortall.net>
Tue, 1 Nov 2005 08:26:19 +0000 (08:26 -0000)
* 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
modules/objfmts/elf/elf.c
modules/objfmts/elf/elf.h
modules/objfmts/elf/tests/Makefile.inc
modules/objfmts/elf/tests/elftypesize.asm [new file with mode: 0644]
modules/objfmts/elf/tests/elftypesize.errwarn [new file with mode: 0644]
modules/objfmts/elf/tests/elftypesize.hex [new file with mode: 0644]

index 5b58df7099614aba24e4d893dfdc1af73ef6aa86..fa0604f796f19b117479cae6425ecacbf570b6c5 100644 (file)
@@ -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);
        }
 
index 36f6ccc8503dd8e4365c8c1574cb69f4080e46cb..7b0734f90cad03bd33a2895990b47d8eed583243 100644 (file)
@@ -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,
index 5a7fb159ead0013b73eeb24cff283d2374da29a2..bad69b7a7965eb0c4011e4251b33716b97004753 100644 (file)
@@ -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,
index f39c04a50557ad55ccbfb03cac94fc7140323ead..a20402bb2e6d91311986e9c88634e1e968f6f6fe 100644 (file)
@@ -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 (file)
index 0000000..88a72da
--- /dev/null
@@ -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 (file)
index 0000000..e69de29
diff --git a/modules/objfmts/elf/tests/elftypesize.hex b/modules/objfmts/elf/tests/elftypesize.hex
new file mode 100644 (file)
index 0000000..c9f8d6e
--- /dev/null
@@ -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