[PATCH] ld: Add ehdr_start to bfd_link_hash_entry
H.J. Lu
hjl.tools@gmail.com
Wed Jan 5 02:10:35 GMT 2022
On Tue, Jan 4, 2022 at 5:57 PM Alan Modra <amodra@gmail.com> wrote:
>
> On Sat, Jan 01, 2022 at 07:37:19PM -0800, H.J. Lu via Binutils wrote:
> > __ehdr_start is a special symbol which is undefined during link. It
> > becomes defined almost at the last minute if it is referenced. Add
> > ehdr_start to bfd_link_hash_entry for __ehdr_start so that ELF linker
> > can properly handle it.
>
> We make some effort in ldelf_before_allocation to handle __ehdr_start
> for bfd_elf_size_dynamic_sections by defining it early. Where else do
> we need special handling?
>
> Hmm, I'm guessing for your DT_RELR support.
Correct. I get DT_RELR almost working on x86. When computing
relocation address for DT_RELR, I have
h = relative_reloc->data[i].h;
if (h != NULL)
{
if (h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
{
sym_sec = h->root.u.def.section;
relocation = (h->root.u.def.value
+ sym_sec->output_section->vma
+ sym_sec->output_offset);
}
else if (bfd_link_pic (info) && h->root.ehdr_start)
{
/* Assume that __ehdr_start in PIE and shared library
is 0. */
relocation = 0;
info->zero_ehdr_start = 1;
}
else
abort ();
At the sizing phase, I got
Breakpoint 1, elf_x86_size_or_finish_relative_reloc (is_x86_64=true,
align_mask=1, info=0x6bfa20 <link_info>, htab=0x6dbd30,
unaligned=false, outrel=0x0) at
/export/gnu/import/git/gitlab/x86-binutils/bfd/elfxx-x86.c:1435
1435 if (h->root.type == bfd_link_hash_defined
(gdb) p *h
$3 = {root = {root = {next = 0x0, string = 0x6f29e6 "__ehdr_start",
hash = 78192523}, type = bfd_link_hash_undefined,
non_ir_ref_regular = 0, non_ir_ref_dynamic = 0, linker_def = 0,
ldscript_def = 0, ehdr_start = 1, rel_from_abs = 1, u = {undef = {
next = 0x0, abfd = 0x6eb4e0}, def = {next = 0x0, section = 0x6eb4e0,
value = 0}, i = {next = 0x0, link = 0x6eb4e0, warning = 0x0}, c = {
next = 0x0, p = 0x6eb4e0, size = 0}}}, indx = -1, dynindx = -1, got = {
refcount = -1, offset = 18446744073709551615, glist = 0xffffffffffffffff,
plist = 0xffffffffffffffff}, plt = {refcount = -1,
offset = 18446744073709551615, glist = 0xffffffffffffffff,
plist = 0xffffffffffffffff}, size = 0, dyn_relocs = 0x6f4180, type = 0,
other = 2, target_internal = 0, ref_regular = 1, def_regular = 1,
ref_dynamic = 0, def_dynamic = 0, ref_regular_nonweak = 1,
ref_ir_nonweak = 0, dynamic_adjusted = 0, needs_copy = 0, needs_plt = 0,
non_elf = 0, versioned = unversioned, forced_local = 1, dynamic = 0,
mark = 0, non_got_ref = 0, dynamic_def = 0, ref_dynamic_nonweak = 0,
pointer_equality_needed = 1, unique_global = 0, protected_def = 0,
start_stop = 0, is_weakalias = 0, dynstr_index = 0, u = {alias = 0x0,
elf_hash_value = 0}, verinfo = {verdef = 0x0, vertree = 0x0}, u2 = {
start_stop_section = 0x0, vtable = 0x0}}
(gdb)
I can use 0 as a relocation value since it isn't final. But at the
finishing phase, I now got
Breakpoint 1, elf_x86_size_or_finish_relative_reloc (is_x86_64=true,
align_mask=0, info=0x6bfa20 <link_info>, htab=0x6dbd30,
unaligned=true, outrel=0x7fffffffd6c0) at
/export/gnu/import/git/gitlab/x86-binutils/bfd/elfxx-x86.c:1435
1435 if (h->root.type == bfd_link_hash_defined
(gdb) p *h
$4 = {root = {root = {next = 0x0, string = 0x6f29e6 "__ehdr_start",
hash = 78192523}, type = bfd_link_hash_defined, non_ir_ref_regular = 0,
non_ir_ref_dynamic = 0, linker_def = 0, ldscript_def = 0, ehdr_start = 1,
rel_from_abs = 1, u = {undef = {next = 0x0, abfd = 0x6dadd0}, def = {
next = 0x0, section = 0x6dadd0, value = 18446744073709551104}, i = {
next = 0x0, link = 0x6dadd0,
warning = 0xfffffffffffffe00 <error: Cannot access memory at
address 0xfffffffffffffe00>}, c = {next = 0x0, p = 0x6dadd0,
size = 18446744073709551104}}}, indx = -1, dynindx = -1, got = {
refcount = -1, offset = 18446744073709551615, glist = 0xffffffffffffffff,
plist = 0xffffffffffffffff}, plt = {refcount = -1,
offset = 18446744073709551615, glist = 0xffffffffffffffff,
plist = 0xffffffffffffffff}, size = 0, dyn_relocs = 0x6f4180, type = 0,
other = 2, target_internal = 0, ref_regular = 1, def_regular = 1,
ref_dynamic = 0, def_dynamic = 0, ref_regular_nonweak = 1,
ref_ir_nonweak = 0, dynamic_adjusted = 0, needs_copy = 0, needs_plt = 0,
non_elf = 0, versioned = unversioned, forced_local = 1, dynamic = 0,
mark = 0, non_got_ref = 0, dynamic_def = 0, ref_dynamic_nonweak = 0,
pointer_equality_needed = 1, unique_global = 0, protected_def = 0,
start_stop = 0, is_weakalias = 0, dynstr_index = 0, u = {alias = 0x0,
elf_hash_value = 0}, verinfo = {verdef = 0x0, vertree = 0x0}, u2 = {
start_stop_section = 0x0, vtable = 0x0}}
(gdb)
I think my patch can be dropped.
Thanks.
--
H.J.
More information about the Binutils
mailing list