ldlang.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 2,418 行 · 第 1/5 页
C
2,418 行
lang_reasonable_defaults (){#if 0 lang_output_section_statement_lookup (".text"); lang_output_section_statement_lookup (".data"); default_common_section = lang_output_section_statement_lookup (".bss"); if (placed_commons == false) { lang_wild_statement_type *new = new_stat (lang_wild_statement, &default_common_section->children); new->section_name = "COMMON"; new->filename = (char *) NULL; lang_list_init (&new->children); }#endif}/* Add the supplied name to the symbol table as an undefined reference. Remove items from the chain as we open input bfds. */typedef struct ldlang_undef_chain_list{ struct ldlang_undef_chain_list *next; char *name;} ldlang_undef_chain_list_type;static ldlang_undef_chain_list_type *ldlang_undef_chain_list_head;voidldlang_add_undef (name) const char *const name;{ ldlang_undef_chain_list_type *new = ((ldlang_undef_chain_list_type *) stat_alloc (sizeof (ldlang_undef_chain_list_type))); new->next = ldlang_undef_chain_list_head; ldlang_undef_chain_list_head = new; new->name = xstrdup (name);}/* Run through the list of undefineds created above and place them into the linker hash table as undefined symbols belonging to the script file. */static voidlang_place_undefineds (){ ldlang_undef_chain_list_type *ptr; for (ptr = ldlang_undef_chain_list_head; ptr != (ldlang_undef_chain_list_type *) NULL; ptr = ptr->next) { struct bfd_link_hash_entry *h; h = bfd_link_hash_lookup (link_info.hash, ptr->name, true, false, true); if (h == (struct bfd_link_hash_entry *) NULL) einfo (_("%P%F: bfd_link_hash_lookup failed: %E\n")); if (h->type == bfd_link_hash_new) { h->type = bfd_link_hash_undefined; h->u.undef.abfd = NULL; bfd_link_add_undef (link_info.hash, h); } }}/* Open input files and attatch to output sections. */static voidmap_input_to_output_sections (s, target, output_section_statement) lang_statement_union_type *s; const char *target; lang_output_section_statement_type *output_section_statement;{ for (; s != (lang_statement_union_type *) NULL; s = s->next) { switch (s->header.type) { case lang_wild_statement_enum: wild (&s->wild_statement, s->wild_statement.section_name, s->wild_statement.filename, target, output_section_statement); break; case lang_constructors_statement_enum: map_input_to_output_sections (constructor_list.head, target, output_section_statement); break; case lang_output_section_statement_enum: map_input_to_output_sections (s->output_section_statement.children.head, target, &s->output_section_statement); break; case lang_output_statement_enum: break; case lang_target_statement_enum: target = s->target_statement.target; break; case lang_group_statement_enum: map_input_to_output_sections (s->group_statement.children.head, target, output_section_statement); break; case lang_fill_statement_enum: case lang_input_section_enum: case lang_object_symbols_statement_enum: case lang_data_statement_enum: case lang_reloc_statement_enum: case lang_padding_statement_enum: case lang_input_statement_enum: if (output_section_statement != NULL && output_section_statement->bfd_section == NULL) init_os (output_section_statement); break; case lang_assignment_statement_enum: if (output_section_statement != NULL && output_section_statement->bfd_section == NULL) init_os (output_section_statement); /* Make sure that any sections mentioned in the assignment are initialized. */ exp_init_os (s->assignment_statement.exp); break; case lang_afile_asection_pair_statement_enum: FAIL (); break; case lang_address_statement_enum: /* Mark the specified section with the supplied address. */ { lang_output_section_statement_type *os = lang_output_section_statement_lookup (s->address_statement.section_name); if (os->bfd_section == NULL) init_os (os); os->addr_tree = s->address_statement.address; } break; } }}static voidprint_output_section_statement (output_section_statement) lang_output_section_statement_type *output_section_statement;{ asection *section = output_section_statement->bfd_section; int len; if (output_section_statement != abs_output_section) { minfo ("\n%s", output_section_statement->name); if (section != NULL) { print_dot = section->vma; len = strlen (output_section_statement->name); if (len >= SECTION_NAME_MAP_LENGTH - 1) { print_nl (); len = 0; } while (len < SECTION_NAME_MAP_LENGTH) { print_space (); ++len; } minfo ("0x%V %W", section->vma, section->_raw_size); if (output_section_statement->load_base != NULL) { bfd_vma addr; addr = exp_get_abs_int (output_section_statement->load_base, 0, "load base", lang_final_phase_enum); minfo (_(" load address 0x%V"), addr); } } print_nl (); } print_statement_list (output_section_statement->children.head, output_section_statement);}static voidprint_assignment (assignment, output_section) lang_assignment_statement_type *assignment; lang_output_section_statement_type *output_section;{ int i; etree_value_type result; for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++) print_space (); result = exp_fold_tree (assignment->exp->assign.src, output_section, lang_final_phase_enum, print_dot, &print_dot); if (result.valid_p) minfo ("0x%V", result.value + result.section->bfd_section->vma); else { minfo ("*undef* ");#ifdef BFD64 minfo (" ");#endif } minfo (" "); exp_print_tree (assignment->exp); print_nl ();}static voidprint_input_statement (statm) lang_input_statement_type *statm;{ if (statm->filename != (char *) NULL) { fprintf (config.map_file, "LOAD %s\n", statm->filename); }}/* Print all symbols defined in a particular section. This is called via bfd_link_hash_traverse. */static booleanprint_one_symbol (hash_entry, ptr) struct bfd_link_hash_entry *hash_entry; PTR ptr;{ asection *sec = (asection *) ptr; if ((hash_entry->type == bfd_link_hash_defined || hash_entry->type == bfd_link_hash_defweak) && sec == hash_entry->u.def.section) { int i; for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++) print_space (); minfo ("0x%V ", (hash_entry->u.def.value + hash_entry->u.def.section->output_offset + hash_entry->u.def.section->output_section->vma)); minfo (" %T\n", hash_entry->root.string); } return true;}/* Print information about an input section to the map file. */static voidprint_input_section (in) lang_input_section_type *in;{ asection *i = in->section; bfd_size_type size = i->_cooked_size != 0 ? i->_cooked_size : i->_raw_size; unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, ldfile_output_machine); if (size != 0) { print_space (); minfo ("%s", i->name); if (i->output_section != NULL) { int len; len = 1 + strlen (i->name); if (len >= SECTION_NAME_MAP_LENGTH - 1) { print_nl (); len = 0; } while (len < SECTION_NAME_MAP_LENGTH) { print_space (); ++len; } minfo ("0x%V %W %B\n", i->output_section->vma + i->output_offset, size / opb, i->owner); if (i->_cooked_size != 0 && i->_cooked_size != i->_raw_size) { len = SECTION_NAME_MAP_LENGTH + 3;#ifdef BFD64 len += 16;#else len += 8;#endif while (len > 0) { print_space (); --len; } minfo (_("%W (size before relaxing)\n"), i->_raw_size); } bfd_link_hash_traverse (link_info.hash, print_one_symbol, (PTR) i); print_dot = i->output_section->vma + i->output_offset + size / opb; } }}static voidprint_fill_statement (fill) lang_fill_statement_type *fill;{ fprintf (config.map_file, " FILL mask 0x%x\n", fill->fill);}static voidprint_data_statement (data) lang_data_statement_type *data;{ int i; bfd_vma addr; bfd_size_type size; const char *name; unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, ldfile_output_machine); for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++) print_space (); addr = data->output_vma; if (data->output_section != NULL) addr += data->output_section->vma; switch (data->type) { default: abort (); case BYTE: size = BYTE_SIZE; name = "BYTE"; break; case SHORT: size = SHORT_SIZE; name = "SHORT"; break; case LONG: size = LONG_SIZE; name = "LONG"; break; case QUAD: size = QUAD_SIZE; name = "QUAD"; break; case SQUAD: size = QUAD_SIZE; name = "SQUAD"; break; } minfo ("0x%V %W %s 0x%v", addr, size, name, data->value); if (data->exp->type.node_class != etree_value) { print_space (); exp_print_tree (data->exp); } print_nl (); print_dot = addr + size / opb;}/* Print an address statement. These are generated by options like -Ttext. */static voidprint_address_statement (address) lang_address_statement_type *address;{ minfo (_("Address of section %s set to "), address->section_name); exp_print_tree (address->address); print_nl ();}/* Print a reloc statement. */static voidprint_reloc_statement (reloc) lang_reloc_statement_type *reloc;{ int i; bfd_vma addr; bfd_size_type size; unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, ldfile_output_machine); for (i = 0; i < SECTION_NAME_MAP_LENGTH; i++) print_space (); addr = reloc->output_vma; if (reloc->output_section != NULL) addr += reloc->output_section->vma; size = bfd_get_reloc_size (reloc->howto); minfo ("0x%V %W RELOC %s ", addr, size, reloc->howto->name); if (reloc->name != NULL) minfo ("%s+", reloc->name); else minfo ("%s+", reloc->section->name); exp_print_tree (reloc->addend_exp); print_nl (); print_dot = addr + size / opb;}static voidprint_padding_statement (s) lang_padding_statement_type *s;{ int len; bfd_vma addr; unsigned opb = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, ldfile_output_machine); minfo (" *fill*"); len = sizeof " *fill*" - 1; while (len < SECTION_NAME_MAP_LENGTH) { print_space (); ++len; } addr = s->output_offset; if (s->output_section != NULL) addr += s->output_section->vma; minfo ("0x%V %W", addr, s->size); if (s->fill != 0) minfo (" %u", s->fill); print_nl (); print_dot = addr + s->size / opb;}static voidprint_wild_statement (w, os) lang_wild_statement_type *w; lang_output_section_statement_type *os;{ print_space (); if (w->filenames_sorted) minfo ("SORT("); if (w->exclude_filename_list != NULL) { name_list *tmp; minfo ("EXCLUDE_FILE ( %s", w->exclude_filename_list->name); for (tmp
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?