bfd.c
来自「基于4个mips核的noc设计」· C语言 代码 · 共 1,238 行 · 第 1/3 页
C
1,238 行
The initial motivation for, and use of, this routine is not so we can get the exact size of the object the BFD applies to, since that might not be generally possible (archive members for example). It would be ideal if someone could eventually modify it so that such results were guaranteed. Instead, we want to ask questions like "is this NNN byte sized object I'm about to try read from file offset YYY reasonable?" As as example of where we might do this, some object formats use string tables for which the first <<sizeof (long)>> bytes of the table contain the size of the table itself, including the size bytes. If an application tries to read what it thinks is one of these string tables, without some way to validate the size, and for some reason the size is wrong (byte swapping error, wrong location for the string table, etc.), the only clue is likely to be a read error when it tries to read the table, or a "virtual memory exhausted" error when it tries to allocate 15 bazillon bytes of space for the 15 bazillon byte table it is about to read. This function at least allows us to answer the quesion, "is the size reasonable?".*/longbfd_get_size (abfd) bfd *abfd;{ FILE *fp; struct stat buf; if ((abfd->flags & BFD_IN_MEMORY) != 0) return ((struct bfd_in_memory *) abfd->iostream)->size; fp = bfd_cache_lookup (abfd); if (0 != fstat (fileno (fp), &buf)) return 0; return buf.st_size;}/*FUNCTION bfd_get_gp_sizeSYNOPSIS int bfd_get_gp_size(bfd *abfd);DESCRIPTION Return the maximum size of objects to be optimized using the GP register under MIPS ECOFF. This is typically set by the <<-G>> argument to the compiler, assembler or linker.*/intbfd_get_gp_size (abfd) bfd *abfd;{ if (abfd->format == bfd_object) { if (abfd->xvec->flavour == bfd_target_ecoff_flavour) return ecoff_data (abfd)->gp_size; else if (abfd->xvec->flavour == bfd_target_elf_flavour) return elf_gp_size (abfd); } return 0;}/*FUNCTION bfd_set_gp_sizeSYNOPSIS void bfd_set_gp_size(bfd *abfd, int i);DESCRIPTION Set the maximum size of objects to be optimized using the GP register under ECOFF or MIPS ELF. This is typically set by the <<-G>> argument to the compiler, assembler or linker.*/voidbfd_set_gp_size (abfd, i) bfd *abfd; int i;{ /* Don't try to set GP size on an archive or core file! */ if (abfd->format != bfd_object) return; if (abfd->xvec->flavour == bfd_target_ecoff_flavour) ecoff_data (abfd)->gp_size = i; else if (abfd->xvec->flavour == bfd_target_elf_flavour) elf_gp_size (abfd) = i;}/* Get the GP value. This is an internal function used by some of the relocation special_function routines on targets which support a GP register. */bfd_vma_bfd_get_gp_value (abfd) bfd *abfd;{ if (abfd->format == bfd_object) { if (abfd->xvec->flavour == bfd_target_ecoff_flavour) return ecoff_data (abfd)->gp; else if (abfd->xvec->flavour == bfd_target_elf_flavour) return elf_gp (abfd); } return 0;}/* Set the GP value. */void_bfd_set_gp_value (abfd, v) bfd *abfd; bfd_vma v;{ if (abfd->format != bfd_object) return; if (abfd->xvec->flavour == bfd_target_ecoff_flavour) ecoff_data (abfd)->gp = v; else if (abfd->xvec->flavour == bfd_target_elf_flavour) elf_gp (abfd) = v;}/*FUNCTION bfd_scan_vmaSYNOPSIS bfd_vma bfd_scan_vma(CONST char *string, CONST char **end, int base);DESCRIPTION Convert, like <<strtoul>>, a numerical expression @var{string} into a <<bfd_vma>> integer, and return that integer. (Though without as many bells and whistles as <<strtoul>>.) The expression is assumed to be unsigned (i.e., positive). If given a @var{base}, it is used as the base for conversion. A base of 0 causes the function to interpret the string in hex if a leading "0x" or "0X" is found, otherwise in octal if a leading zero is found, otherwise in decimal. Overflow is not detected.*/bfd_vmabfd_scan_vma (string, end, base) CONST char *string; CONST char **end; int base;{ bfd_vma value; int digit; /* Let the host do it if possible. */ if (sizeof (bfd_vma) <= sizeof (unsigned long)) return (bfd_vma) strtoul (string, (char **) end, base); /* A negative base makes no sense, and we only need to go as high as hex. */ if ((base < 0) || (base > 16)) return (bfd_vma) 0; if (base == 0) { if (string[0] == '0') { if ((string[1] == 'x') || (string[1] == 'X')) base = 16; /* XXX should we also allow "0b" or "0B" to set base to 2? */ else base = 8; } else base = 10; } if ((base == 16) && (string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X'))) string += 2; /* XXX should we also skip over "0b" or "0B" if base is 2? *//* Speed could be improved with a table like hex_value[] in gas. */#define HEX_VALUE(c) \ (isxdigit ((unsigned char) c) \ ? (isdigit ((unsigned char) c) \ ? (c - '0') \ : (10 + c - (islower ((unsigned char) c) ? 'a' : 'A'))) \ : 42) for (value = 0; (digit = HEX_VALUE(*string)) < base; string++) { value = value * base + digit; } if (end) *end = string; return value;}/*FUNCTION bfd_copy_private_bfd_dataSYNOPSIS boolean bfd_copy_private_bfd_data(bfd *ibfd, bfd *obfd);DESCRIPTION Copy private BFD information from the BFD @var{ibfd} to the the BFD @var{obfd}. Return <<true>> on success, <<false>> on error. Possible error returns are: o <<bfd_error_no_memory>> - Not enough memory exists to create private data for @var{obfd}..#define bfd_copy_private_bfd_data(ibfd, obfd) \. BFD_SEND (obfd, _bfd_copy_private_bfd_data, \. (ibfd, obfd))*//*FUNCTION bfd_merge_private_bfd_dataSYNOPSIS boolean bfd_merge_private_bfd_data(bfd *ibfd, bfd *obfd);DESCRIPTION Merge private BFD information from the BFD @var{ibfd} to the the output file BFD @var{obfd} when linking. Return <<true>> on success, <<false>> on error. Possible error returns are: o <<bfd_error_no_memory>> - Not enough memory exists to create private data for @var{obfd}..#define bfd_merge_private_bfd_data(ibfd, obfd) \. BFD_SEND (obfd, _bfd_merge_private_bfd_data, \. (ibfd, obfd))*//*FUNCTION bfd_set_private_flagsSYNOPSIS boolean bfd_set_private_flags(bfd *abfd, flagword flags);DESCRIPTION Set private BFD flag information in the BFD @var{abfd}. Return <<true>> on success, <<false>> on error. Possible error returns are: o <<bfd_error_no_memory>> - Not enough memory exists to create private data for @var{obfd}..#define bfd_set_private_flags(abfd, flags) \. BFD_SEND (abfd, _bfd_set_private_flags, \. (abfd, flags))*//*FUNCTION stuffDESCRIPTION Stuff which should be documented:.#define bfd_sizeof_headers(abfd, reloc) \. BFD_SEND (abfd, _bfd_sizeof_headers, (abfd, reloc))..#define bfd_find_nearest_line(abfd, sec, syms, off, file, func, line) \. BFD_SEND (abfd, _bfd_find_nearest_line, (abfd, sec, syms, off, file, func, line)).. {* Do these three do anything useful at all, for any back end? *}.#define bfd_debug_info_start(abfd) \. BFD_SEND (abfd, _bfd_debug_info_start, (abfd))..#define bfd_debug_info_end(abfd) \. BFD_SEND (abfd, _bfd_debug_info_end, (abfd))..#define bfd_debug_info_accumulate(abfd, section) \. BFD_SEND (abfd, _bfd_debug_info_accumulate, (abfd, section))...#define bfd_stat_arch_elt(abfd, stat) \. BFD_SEND (abfd, _bfd_stat_arch_elt,(abfd, stat))..#define bfd_update_armap_timestamp(abfd) \. BFD_SEND (abfd, _bfd_update_armap_timestamp, (abfd))..#define bfd_set_arch_mach(abfd, arch, mach)\. BFD_SEND ( abfd, _bfd_set_arch_mach, (abfd, arch, mach))..#define bfd_relax_section(abfd, section, link_info, again) \. BFD_SEND (abfd, _bfd_relax_section, (abfd, section, link_info, again))..#define bfd_gc_sections(abfd, link_info) \. BFD_SEND (abfd, _bfd_gc_sections, (abfd, link_info))..#define bfd_link_hash_table_create(abfd) \. BFD_SEND (abfd, _bfd_link_hash_table_create, (abfd))..#define bfd_link_add_symbols(abfd, info) \. BFD_SEND (abfd, _bfd_link_add_symbols, (abfd, info))..#define bfd_final_link(abfd, info) \. BFD_SEND (abfd, _bfd_final_link, (abfd, info))..#define bfd_free_cached_info(abfd) \. BFD_SEND (abfd, _bfd_free_cached_info, (abfd))..#define bfd_get_dynamic_symtab_upper_bound(abfd) \. BFD_SEND (abfd, _bfd_get_dynamic_symtab_upper_bound, (abfd))..#define bfd_print_private_bfd_data(abfd, file)\. BFD_SEND (abfd, _bfd_print_private_bfd_data, (abfd, file))..#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \. BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols))..#define bfd_get_dynamic_reloc_upper_bound(abfd) \. BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd))..#define bfd_canonicalize_dynamic_reloc(abfd, arels, asyms) \. BFD_SEND (abfd, _bfd_canonicalize_dynamic_reloc, (abfd, arels, asyms))..extern bfd_byte *bfd_get_relocated_section_contents. PARAMS ((bfd *, struct bfd_link_info *,. struct bfd_link_order *, bfd_byte *,. boolean, asymbol **));.*/bfd_byte *bfd_get_relocated_section_contents (abfd, link_info, link_order, data, relocateable, symbols) bfd *abfd; struct bfd_link_info *link_info; struct bfd_link_order *link_order; bfd_byte *data; boolean relocateable; asymbol **symbols;{ bfd *abfd2; bfd_byte *(*fn) PARAMS ((bfd *, struct bfd_link_info *, struct bfd_link_order *, bfd_byte *, boolean, asymbol **)); if (link_order->type == bfd_indirect_link_order) { abfd2 = link_order->u.indirect.section->owner; if (abfd2 == 0) abfd2 = abfd; } else abfd2 = abfd; fn = abfd2->xvec->_bfd_get_relocated_section_contents; return (*fn) (abfd, link_info, link_order, data, relocateable, symbols);}/* Record information about an ELF program header. */booleanbfd_record_phdr (abfd, type, flags_valid, flags, at_valid, at, includes_filehdr, includes_phdrs, count, secs) bfd *abfd; unsigned long type; boolean flags_valid; flagword flags; boolean at_valid; bfd_vma at; boolean includes_filehdr; boolean includes_phdrs; unsigned int count; asection **secs;{ struct elf_segment_map *m, **pm; if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) return true; m = ((struct elf_segment_map *) bfd_alloc (abfd, (sizeof (struct elf_segment_map) + ((size_t) count - 1) * sizeof (asection *)))); if (m == NULL) return false; m->next = NULL; m->p_type = type; m->p_flags = flags; m->p_paddr = at; m->p_flags_valid = flags_valid; m->p_paddr_valid = at_valid; m->includes_filehdr = includes_filehdr; m->includes_phdrs = includes_phdrs; m->count = count; if (count > 0) memcpy (m->sections, secs, count * sizeof (asection *)); for (pm = &elf_tdata (abfd)->segment_map; *pm != NULL; pm = &(*pm)->next) ; *pm = m; return true;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?