static struct ld_input_section * _find_and_create_gotplt_section(struct ld *ld, int create) { struct ld_input_section *is; /* Check if the GOT (for PLT) section is already created. */ is = ld_input_find_internal_section(ld, ".got.plt"); if (is != NULL) return (is); if (create) { is = ld_input_add_internal_section(ld, ".got.plt"); is->is_entsize = 4; is->is_align = 4; is->is_type = SHT_PROGBITS; is->is_flags = SHF_ALLOC | SHF_WRITE; /* Reserve space for the initial entries. */ (void) ld_input_reserve_ibuf(is, 3); /* Create _GLOBAL_OFFSET_TABLE_ symbol. */ ld_symbols_add_internal(ld, "_GLOBAL_OFFSET_TABLE_", 0, 0, is->is_index, STB_LOCAL, STT_OBJECT, STV_HIDDEN, is, NULL); } return (is); }
void ld_dynamic_reserve_dynbss_entry(struct ld *ld, struct ld_symbol *lsb) { struct ld_input *li; struct ld_input_section *dynbss, *is; u_int64_t a; /* Create .dynbss section if it doesn't yet exist. */ dynbss = ld_input_find_internal_section(ld, ".dynbss"); if (dynbss == NULL) { dynbss = ld_input_add_internal_section(ld, ".dynbss"); dynbss->is_type = SHT_NOBITS; } li = lsb->lsb_input; assert(li != NULL && li->li_type == LIT_DSO); /* * TODO: we don't have to create copy relocation * for every import object. Some import objects * are read-only, in that case we can create other * dynamic relocations for them. */ /* * If the section to which the symbols belong has a larger * alignment requirement, we increase .dynbss section alignment * accordingly. XXX What if it is a DSO common symbol? */ is = NULL; if (lsb->lsb_shndx != SHN_COMMON) { assert(lsb->lsb_shndx < li->li_shnum - 1); is = &li->li_is[lsb->lsb_shndx]; if (is->is_align > dynbss->is_align) dynbss->is_align = is->is_align; } /* * Calculate the alignment for this object. */ if (is != NULL) { for (a = is->is_align; a > 1; a >>= 1) { if ((lsb->lsb_value - is->is_off) % a == 0) break; } } else
static struct ld_input_section * _find_and_create_got_section(struct ld *ld, int create) { struct ld_input_section *is; /* Check if the GOT section is already created. */ is = ld_input_find_internal_section(ld, ".got"); if (is != NULL) return (is); if (create) { is = ld_input_add_internal_section(ld, ".got"); is->is_entsize = 4; is->is_align = 4; is->is_type = SHT_PROGBITS; is->is_flags = SHF_ALLOC | SHF_WRITE; } return (is); }
static struct ld_input_section * _find_and_create_plt_section(struct ld *ld, int create) { struct ld_input_section *is; /* Check if the PLT section is already created. */ is = ld_input_find_internal_section(ld, ".plt"); if (is != NULL) return (is); if (create) { is = ld_input_add_internal_section(ld, ".plt"); is->is_entsize = 4; is->is_align = 4; is->is_type = SHT_PROGBITS; is->is_flags = SHF_ALLOC | SHF_EXECINSTR; /* Reserve space for the initial entry. */ (void) ld_input_reserve_ibuf(is, 1); } return (is); }