📄 obj-elf.c
字号:
do { name = input_line_pointer; c = get_symbol_end (); symbolP = symbol_find_or_make (name); *input_line_pointer = c; SKIP_WHITESPACE (); bfdsym = symbol_get_bfdsym (symbolP); elfsym = elf_symbol_from (bfd_asymbol_bfd (bfdsym), bfdsym); assert (elfsym); elfsym->internal_elf_sym.st_other = visibility; if (c == ',') { input_line_pointer ++; SKIP_WHITESPACE (); if (*input_line_pointer == '\n') c = '\n'; } } while (c == ','); demand_empty_rest_of_line ();}static segT previous_section;static int previous_subsection;struct section_stack{ struct section_stack *next; segT seg, prev_seg; int subseg, prev_subseg;};static struct section_stack *section_stack;/* Handle the .section pseudo-op. This code supports two different syntaxes. The first is found on Solaris, and looks like .section ".sec1",#alloc,#execinstr,#write Here the names after '#' are the SHF_* flags to turn on for the section. I'm not sure how it determines the SHT_* type (BFD doesn't really give us control over the type, anyhow). The second format is found on UnixWare, and probably most SVR4 machines, and looks like .section .sec1,"a",@progbits The quoted string may contain any combination of a, w, x, and represents the SHF_* flags to turn on for the section. The string beginning with '@' can be progbits or nobits. There should be other possibilities, but I don't know what they are. In any case, BFD doesn't really let us set the section type. *//* Certain named sections have particular defined types, listed on p. 4-19 of the ABI. */struct special_section{ const char *name; int type; int attributes;};static struct special_section const special_sections[] ={ { ".bss", SHT_NOBITS, SHF_ALLOC + SHF_WRITE }, { ".comment", SHT_PROGBITS, 0 }, { ".data", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, { ".data1", SHT_PROGBITS, SHF_ALLOC + SHF_WRITE }, { ".debug", SHT_PROGBITS, 0 }, { ".fini", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, { ".init", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR }, { ".line", SHT_PROGBITS, 0 }, { ".note", SHT_NOTE, 0 }, { ".rodata", SHT_PROGBITS, SHF_ALLOC }, { ".rodata1", SHT_PROGBITS, SHF_ALLOC }, { ".text", SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },#ifdef ELF_TC_SPECIAL_SECTIONS ELF_TC_SPECIAL_SECTIONS#endif#if 0 /* The following section names are special, but they can not reasonably appear in assembler code. Some of the attributes are processor dependent. */ { ".dynamic", SHT_DYNAMIC, SHF_ALLOC /* + SHF_WRITE */ }, { ".dynstr", SHT_STRTAB, SHF_ALLOC }, { ".dynsym", SHT_DYNSYM, SHF_ALLOC }, { ".got", SHT_PROGBITS, 0 }, { ".hash", SHT_HASH, SHF_ALLOC }, { ".interp", SHT_PROGBITS, /* SHF_ALLOC */ }, { ".plt", SHT_PROGBITS, 0 }, { ".shstrtab",SHT_STRTAB, 0 }, { ".strtab", SHT_STRTAB, /* SHF_ALLOC */ }, { ".symtab", SHT_SYMTAB, /* SHF_ALLOC */ },#endif { NULL, 0, 0 }};voidobj_elf_change_section (name, type, attr, push) char *name; int type, attr, push;{ asection *old_sec; segT sec; flagword flags; int i;#ifdef md_flush_pending_output md_flush_pending_output ();#endif /* Switch to the section, creating it if necessary. */ if (push) { struct section_stack *elt; elt = xmalloc (sizeof (struct section_stack)); elt->next = section_stack; elt->seg = now_seg; elt->prev_seg = previous_section; elt->subseg = now_subseg; elt->prev_subseg = previous_subsection; section_stack = elt; } previous_section = now_seg; previous_subsection = now_subseg; old_sec = bfd_get_section_by_name (stdoutput, name); sec = subseg_new (name, 0); /* See if this is one of the special sections. */ for (i = 0; special_sections[i].name != NULL; i++) if (strcmp (name, special_sections[i].name) == 0) { if (type == SHT_NULL) type = special_sections[i].type; else if (type != special_sections[i].type) { if (old_sec == NULL) { as_warn (_("Setting incorrect section type for %s"), name); } else { as_warn (_("Ignoring incorrect section type for %s"), name); type = special_sections[i].type; } } if ((attr &~ special_sections[i].attributes) != 0 && old_sec == NULL) { /* As a GNU extension, we permit a .note section to be allocatable. If the linker sees an allocateable .note section, it will create a PT_NOTE segment in the output file. */ if (strcmp (name, ".note") != 0 || attr != SHF_ALLOC) as_warn (_("Setting incorrect section attributes for %s"), name); } attr |= special_sections[i].attributes; break; } /* Convert ELF type and flags to BFD flags. */ flags = (SEC_RELOC | ((attr & SHF_WRITE) ? 0 : SEC_READONLY) | ((attr & SHF_ALLOC) ? SEC_ALLOC : 0) | (((attr & SHF_ALLOC) && type != SHT_NOBITS) ? SEC_LOAD : 0) | ((attr & SHF_EXECINSTR) ? SEC_CODE : 0));#ifdef md_elf_section_flags flags = md_elf_section_flags (flags, attr, type);#endif if (old_sec == NULL) { symbolS *secsym; /* Prevent SEC_HAS_CONTENTS from being inadvertently set. */ if (type == SHT_NOBITS) seg_info (sec)->bss = 1; bfd_set_section_flags (stdoutput, sec, flags); /* Add a symbol for this section to the symbol table. */ secsym = symbol_find (name); if (secsym != NULL) symbol_set_bfdsym (secsym, sec->symbol); else symbol_table_insert (section_symbol (sec)); } else if (attr != 0) { /* If section attributes are specified the second time we see a particular section, then check that they are the same as we saw the first time. */ if ((old_sec->flags ^ flags) & (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE | SEC_EXCLUDE | SEC_SORT_ENTRIES)) as_warn (_("Ignoring changed section attributes for %s"), name); }#ifdef md_elf_section_change_hook md_elf_section_change_hook ();#endif}intobj_elf_parse_section_letters (str, len) char *str; size_t len;{ int attr = 0; while (len > 0) { switch (*str) { case 'a': attr |= SHF_ALLOC; break; case 'w': attr |= SHF_WRITE; break; case 'x': attr |= SHF_EXECINSTR; break; default: { char *bad_msg = _("Unrecognized .section attribute: want a,w,x");#ifdef md_elf_section_letter int md_attr = md_elf_section_letter (*str, &bad_msg); if (md_attr >= 0) attr |= md_attr; else#endif { as_warn ("%s", bad_msg); attr = -1; } } break; } str++, len--; } return attr;}intobj_elf_section_word (str, len) char *str; size_t len;{ if (len == 5 && strncmp (str, "write", 5) == 0) return SHF_WRITE; if (len == 5 && strncmp (str, "alloc", 5) == 0) return SHF_ALLOC; if (len == 9 && strncmp (str, "execinstr", 9) == 0) return SHF_EXECINSTR;#ifdef md_elf_section_word { int md_attr = md_elf_section_word (str, len); if (md_attr >= 0) return md_attr; }#endif as_warn (_("Unrecognized section attribute")); return 0;}intobj_elf_section_type (str, len) char *str; size_t len;{ if (len == 8 && strncmp (str, "progbits", 8) == 0) return SHT_PROGBITS; if (len == 6 && strncmp (str, "nobits", 6) == 0) return SHT_NOBITS;#ifdef md_elf_section_type { int md_type = md_elf_section_type (str, len); if (md_type >= 0) return md_type; }#endif as_warn (_("Unrecognized section type")); return 0;}voidobj_elf_section (push) int push;{ char *name, *beg, *end; int type, attr, dummy;#ifndef TC_I370 if (flag_mri) { char mri_type;#ifdef md_flush_pending_output md_flush_pending_output ();#endif previous_section = now_seg; previous_subsection = now_subseg; s_mri_sect (&mri_type);#ifdef md_elf_section_change_hook md_elf_section_change_hook ();#endif return; }#endif /* ! defined (TC_I370) */ /* Get name of section. */ SKIP_WHITESPACE (); if (*input_line_pointer == '"') { name = demand_copy_C_string (&dummy); if (name == NULL) { ignore_rest_of_line (); return; } } else { end = input_line_pointer; while (0 == strchr ("\n\t,; ", *end)) end++; if (end == input_line_pointer) { as_warn (_("Missing section name")); ignore_rest_of_line (); return; } name = xmalloc (end - input_line_pointer + 1); memcpy (name, input_line_pointer, end - input_line_pointer); name[end - input_line_pointer] = '\0'; input_line_pointer = end; } SKIP_WHITESPACE (); type = SHT_NULL; attr = 0; if (*input_line_pointer == ',') { /* Skip the comma. */ ++input_line_pointer; SKIP_WHITESPACE (); if (*input_line_pointer == '"') { beg = demand_copy_C_string (&dummy); if (beg == NULL) { ignore_rest_of_line (); return; } attr |= obj_elf_parse_section_letters (beg, strlen (beg)); SKIP_WHITESPACE (); if (*input_line_pointer == ',') { char c; ++input_line_pointer; SKIP_WHITESPACE (); c = *input_line_pointer; if (c == '"') { beg = demand_copy_C_string (&dummy); if (beg == NULL) { ignore_rest_of_line (); return; } type = obj_elf_section_type (beg, strlen (beg)); } else if (c == '@' || c == '%') { beg = ++input_line_pointer; c = get_symbol_end (); *input_line_pointer = c; type = obj_elf_section_type (beg, input_line_pointer - beg); } } } else { do { char c; SKIP_WHITESPACE (); if (*input_line_pointer != '#') { as_warn (_("Bad .section directive - character following name is not '#'")); ignore_rest_of_line (); return; } beg = ++input_line_pointer; c = get_symbol_end (); *input_line_pointer = c; attr |= obj_elf_section_word (beg, input_line_pointer - beg); SKIP_WHITESPACE (); } while (*input_line_pointer++ == ','); --input_line_pointer; } } demand_empty_rest_of_line (); obj_elf_change_section (name, type, attr, push);}/* Change to the .data section. */voidobj_elf_data (i) int i;{#ifdef md_flush_pending_output md_flush_pending_output ();#endif previous_section = now_seg; previous_subsection = now_subseg; s_data (i);#ifdef md_elf_section_change_hook md_elf_section_change_hook ();#endif}/* Change to the .text section. */voidobj_elf_text (i) int i;{#ifdef md_flush_pending_output md_flush_pending_output ();#endif previous_section = now_seg; previous_subsection = now_subseg; s_text (i);#ifdef md_elf_section_change_hook md_elf_section_change_hook ();#endif}static voidobj_elf_subsection (ignore) int ignore ATTRIBUTE_UNUSED;{ register int temp;#ifdef md_flush_pending_output md_flush_pending_output ();#endif previous_section = now_seg; previous_subsection = now_subseg; temp = get_absolute_expression (); subseg_set (now_seg, (subsegT) temp); demand_empty_rest_of_line ();#ifdef md_elf_section_change_hook md_elf_section_change_hook ();#endif}/* This can be called from the processor backends if they change sections. */voidobj_elf_section_change_hook (){ previous_section = now_seg; previous_subsection = now_subseg;}voidobj_elf_previous (ignore) int ignore ATTRIBUTE_UNUSED;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -