static bfd_boolean s390_elf_create_ifunc_sections (bfd *abfd, struct bfd_link_info *info) { flagword flags; asection *s; const struct elf_backend_data *bed = get_elf_backend_data (abfd); struct elf_link_hash_table *htab = elf_hash_table (info); if (htab->iplt != NULL) return TRUE; flags = bed->dynamic_sec_flags; if (bfd_link_pic (info)) { s = bfd_make_section_with_flags (abfd, ".rela.ifunc", flags | SEC_READONLY); if (s == NULL || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) return FALSE; htab->irelifunc = s; } /* Create .iplt, .rel[a].iplt, and .igot.plt. */ s = bfd_make_section_with_flags (abfd, ".iplt", flags | SEC_CODE | SEC_READONLY); if (s == NULL || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment)) return FALSE; htab->iplt = s; s = bfd_make_section_with_flags (abfd, ".rela.iplt", flags | SEC_READONLY); if (s == NULL || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) return FALSE; htab->irelplt = s; s = bfd_make_section_with_flags (abfd, ".igot.plt", flags); if (s == NULL || !bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) return FALSE; htab->igotplt = s; return TRUE; }
static asection * make_bfd_asection (bfd *abfd, const char *name, flagword flags, bfd_size_type size, bfd_vma vma, file_ptr filepos) { asection *asect; char *newname; newname = bfd_alloc (abfd, (bfd_size_type) strlen (name) + 1); if (!newname) return NULL; strcpy (newname, name); asect = bfd_make_section_with_flags (abfd, newname, flags); if (!asect) return NULL; asect->size = size; asect->vma = vma; asect->filepos = filepos; asect->alignment_power = 2; return asect; }
/* Write resource file */ void write_res_file (const char *fn,const rc_res_directory *resdir) { asection *sec; rc_uint_type language; bfd *abfd; windres_bfd wrbfd; unsigned long sec_length = 0,sec_length_wrote; static const bfd_byte sign[] = { 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; filename = fn; abfd = windres_open_as_binary (filename, 0); sec = bfd_make_section_with_flags (abfd, ".data", (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA)); if (sec == NULL) bfd_fatal ("bfd_make_section"); /* Requiring this is probably a bug in BFD. */ sec->output_section = sec; set_windres_bfd (&wrbfd, abfd, sec, (target_is_bigendian ? WR_KIND_BFD_BIN_B : WR_KIND_BFD_BIN_L)); language = -1; sec_length = write_res_directory ((windres_bfd *) NULL, 0x20UL, resdir, (const rc_res_id *) NULL, (const rc_res_id *) NULL, &language, 1); if (! bfd_set_section_size (abfd, sec, (sec_length + 3) & ~3)) bfd_fatal ("bfd_set_section_size"); if ((sec_length & 3) != 0) set_windres_bfd_content (&wrbfd, sign, sec_length, 4-(sec_length & 3)); set_windres_bfd_content (&wrbfd, sign, 0, sizeof (sign)); language = -1; sec_length_wrote = write_res_directory (&wrbfd, 0x20UL, resdir, (const rc_res_id *) NULL, (const rc_res_id *) NULL, &language, 1); if (sec_length != sec_length_wrote) fatal ("res write failed with different sizes (%lu/%lu).", (unsigned long) sec_length, (unsigned long) sec_length_wrote); bfd_close (abfd); return; }
static asection * make_bfd_asection (bfd *abfd, const char *name, flagword flags, bfd_size_type size, file_ptr offset, unsigned int alignment_power) { asection *asect; asect = bfd_make_section_with_flags (abfd, name, flags); if (!asect) return NULL; asect->size = size; asect->filepos = offset; asect->alignment_power = alignment_power; return asect; }
static const bfd_target * aout_adobe_callback (bfd *abfd) { struct internal_exec *execp = exec_hdr (abfd); asection *sect; struct external_segdesc ext[1]; char *section_name; char try_again[30]; /* Name and number. */ char *newname; int trynum; flagword flags; /* Architecture and machine type -- unknown in this format. */ bfd_set_arch_mach (abfd, bfd_arch_unknown, 0L); /* The positions of the string table and symbol table. */ obj_str_filepos (abfd) = N_STROFF (*execp); obj_sym_filepos (abfd) = N_SYMOFF (*execp); /* Suck up the section information from the file, one section at a time. */ for (;;) { bfd_size_type amt = sizeof (*ext); if (bfd_bread ( ext, amt, abfd) != amt) { if (bfd_get_error () != bfd_error_system_call) bfd_set_error (bfd_error_wrong_format); return NULL; } switch (ext->e_type[0]) { case N_TEXT: section_name = ".text"; flags = SEC_CODE | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS; break; case N_DATA: section_name = ".data"; flags = SEC_DATA | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS; break; case N_BSS: section_name = ".bss"; flags = SEC_DATA | SEC_HAS_CONTENTS; break; case 0: goto no_more_sections; default: (*_bfd_error_handler) (_("%B: Unknown section type in a.out.adobe file: %x\n"), abfd, ext->e_type[0]); goto no_more_sections; } /* First one is called ".text" or whatever; subsequent ones are ".text1", ".text2", ... */ bfd_set_error (bfd_error_no_error); sect = bfd_make_section_with_flags (abfd, section_name, flags); trynum = 0; while (!sect) { if (bfd_get_error () != bfd_error_no_error) /* Some other error -- slide into the sunset. */ return NULL; sprintf (try_again, "%s%d", section_name, ++trynum); sect = bfd_make_section_with_flags (abfd, try_again, flags); } /* Fix the name, if it is a sprintf'd name. */ if (sect->name == try_again) { amt = strlen (sect->name); newname = bfd_zalloc (abfd, amt); if (newname == NULL) return NULL; strcpy (newname, sect->name); sect->name = newname; } /* Assumed big-endian. */ sect->size = ((ext->e_size[0] << 8) | ext->e_size[1] << 8 | ext->e_size[2]); sect->vma = H_GET_32 (abfd, ext->e_virtbase); sect->filepos = H_GET_32 (abfd, ext->e_filebase); /* FIXME XXX alignment? */ /* Set relocation information for first section of each type. */ if (trynum == 0) switch (ext->e_type[0]) { case N_TEXT: sect->rel_filepos = N_TRELOFF (*execp); sect->reloc_count = execp->a_trsize; break; case N_DATA: sect->rel_filepos = N_DRELOFF (*execp); sect->reloc_count = execp->a_drsize; break; default: break; } } no_more_sections: adata (abfd).reloc_entry_size = sizeof (struct reloc_std_external); adata (abfd).symbol_entry_size = sizeof (struct external_nlist); adata (abfd).page_size = 1; /* Not applicable. */ adata (abfd).segment_size = 1; /* Not applicable. */ adata (abfd).exec_bytes_size = EXEC_BYTES_SIZE; return abfd->xvec; }
bfd_boolean _bfd_cgc_create_ifunc_sections (bfd *abfd, struct bfd_link_info *info) { flagword flags, pltflags; asection *s; const struct cgc_backend_data *bed = get_cgc_backend_data (abfd); struct cgc_link_hash_table *htab = cgc_hash_table (info); if (htab->irelifunc != NULL || htab->iplt != NULL) return TRUE; flags = bed->dynamic_sec_flags; pltflags = flags; if (bed->plt_not_loaded) /* We do not clear SEC_ALLOC here because we still want the OS to allocate space for the section; it's just that there's nothing to read in from the object file. */ pltflags &= ~ (SEC_CODE | SEC_LOAD | SEC_HAS_CONTENTS); else pltflags |= SEC_ALLOC | SEC_CODE | SEC_LOAD; if (bed->plt_readonly) pltflags |= SEC_READONLY; if (info->shared) { /* We need to create .rel[a].ifunc for shared objects. */ const char *rel_sec = (bed->rela_plts_and_copies_p ? ".rela.ifunc" : ".rel.ifunc"); s = bfd_make_section_with_flags (abfd, rel_sec, flags | SEC_READONLY); if (s == NULL || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) return FALSE; htab->irelifunc = s; } else { /* We need to create .iplt, .rel[a].iplt, .igot and .igot.plt for static executables. */ s = bfd_make_section_with_flags (abfd, ".iplt", pltflags); if (s == NULL || ! bfd_set_section_alignment (abfd, s, bed->plt_alignment)) return FALSE; htab->iplt = s; s = bfd_make_section_with_flags (abfd, (bed->rela_plts_and_copies_p ? ".rela.iplt" : ".rel.iplt"), flags | SEC_READONLY); if (s == NULL || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) return FALSE; htab->irelplt = s; /* We don't need the .igot section if we have the .igot.plt section. */ if (bed->want_got_plt) s = bfd_make_section_with_flags (abfd, ".igot.plt", flags); else s = bfd_make_section_with_flags (abfd, ".igot", flags); if (s == NULL || !bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) return FALSE; htab->igotplt = s; } return TRUE; }
asection * bfd_make_section (bfd *abfd, const char *name) { return bfd_make_section_with_flags (abfd, name, 0); }
know the size of the section, but that's OK - we just need to create it for now. */ static bfd_boolean linux_link_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED) { flagword flags; asection *s; /* Note that we set the SEC_IN_MEMORY flag. */ flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY; /* We choose to use the name ".linux-dynamic" for the fixup table. Why not? */ s = bfd_make_section_with_flags (abfd, ".linux-dynamic", flags); if (s == NULL || ! bfd_set_section_alignment (abfd, s, 2)) return FALSE; s->size = 0; s->contents = 0; return TRUE; } /* Function to add a single symbol to the linker hash table. This is a wrapper around _bfd_generic_link_add_one_symbol which handles the tweaking needed for dynamic linking support. */ static bfd_boolean linux_add_one_symbol (struct bfd_link_info *info,
static bfd_boolean wasm_scan_name_function_section (bfd *abfd, sec_ptr asect) { bfd_byte *p; bfd_byte *end; bfd_vma payload_size; bfd_vma symcount = 0; tdata_type *tdata = abfd->tdata.any; asymbol *symbols = NULL; sec_ptr space_function_index; if (! asect) return FALSE; if (strcmp (asect->name, WASM_NAME_SECTION) != 0) return FALSE; p = asect->contents; end = asect->contents + asect->size; if (! p) return FALSE; while (p < end) { bfd_byte subsection_code = *p++; if (subsection_code == WASM_FUNCTION_SUBSECTION) break; /* subsection_code is documented to be a varuint7, meaning that it has to be a single byte in the 0 - 127 range. If it isn't, the spec must have changed underneath us, so give up. */ if (subsection_code & 0x80) return FALSE; READ_LEB128 (payload_size, p, end); if (p > p + payload_size) return FALSE; p += payload_size; } if (p >= end) return FALSE; READ_LEB128 (payload_size, p, end); if (p > p + payload_size) return FALSE; if (p + payload_size > end) return FALSE; end = p + payload_size; READ_LEB128 (symcount, p, end); /* Sanity check: each symbol has at least two bytes. */ if (symcount > payload_size/2) return FALSE; tdata->symcount = symcount; space_function_index = bfd_make_section_with_flags (abfd, WASM_SECTION_FUNCTION_INDEX, SEC_READONLY | SEC_CODE); if (! space_function_index) space_function_index = bfd_get_section_by_name (abfd, WASM_SECTION_FUNCTION_INDEX); if (! space_function_index) return FALSE; symbols = bfd_zalloc (abfd, tdata->symcount * sizeof (asymbol)); if (! symbols) return FALSE; for (symcount = 0; p < end && symcount < tdata->symcount; symcount++) { bfd_vma idx; bfd_vma len; char *name; asymbol *sym; READ_LEB128 (idx, p, end); READ_LEB128 (len, p, end); if (p + len < p || p + len > end) goto error_return; name = bfd_zalloc (abfd, len + 1); if (! name) goto error_return; memcpy (name, p, len); p += len; sym = &symbols[symcount]; sym->the_bfd = abfd; sym->name = name; sym->value = idx; sym->flags = BSF_GLOBAL | BSF_FUNCTION; sym->section = space_function_index; sym->udata.p = NULL; } if (symcount < tdata->symcount) goto error_return; tdata->symbols = symbols; abfd->symcount = symcount; return TRUE; error_return: while (symcount) bfd_release (abfd, (void *)symbols[--symcount].name); bfd_release (abfd, symbols); return FALSE; }