This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [GOLD] Support --icf=safe with -pie for x86_64


> Is it safe to assume that 0xe8 is really the start of an instruction?
>
> What if instead you are looking at a modrm or sib for a rip-relative read?
> It may not match in this case (I'm rusty at x86 and would have to look
> at an AMD or Intel manual to know) but your should check this and of
> course for the other encodings below.

You're right, this may result in false positives with some instance getting
classified as a function call when it's not, which in turn might result in some
section getting folded when it shouldn't be.

Ideally, we'd want a way to go from a relocation offset to the beginning of the
instruction containing the relocation. Is there a good way to do that for
x86_64 (short of disassembling the whole section)?

The approach here is inspired by other places in the same file that seem to be
doing something similar (can_convert_mov_to_lea/can_convert_callq_to_direct).
Maybe I'm missing something and there's more context in those other functions
that makes it safe to do so.


> Also, might you have an R_X86_64_PC32 in data and so be looking at the
> high byte of the previous word?

Not sure what you mean here, but this code is only called for text sections, so
we can be sure that the relocation offset is part of an instruction. Did you
mean an instruction with an encoding containning opcode bytes, followed by
immediate operand, which is followed by a R_X86_64_PC32 relocation?

-- 
Rahul


On Thu, Jan 12, 2017 at 5:23 PM, Alan Modra <amodra@gmail.com> wrote:
> On Thu, Jan 12, 2017 at 01:28:49PM -0800, Rahul Chaudhry via binutils wrote:
>> +    case elfcpp::R_X86_64_PC32:
>> +      {
>> +        // This relocation may be used both for function calls and
>> +        // for taking address of a function. We distinguish between
>> +        // them by checking the opcodes.
>> +        section_size_type stype;
>> +        const unsigned char* view = src_obj->section_contents(src_indx,
>> +                                                              &stype,
>> +                                                              true);
>> +
>> +        // call
>> +        if (r_offset >= 1
>> +            && view[r_offset - 1] == 0xe8)
>> +          return false;
>
> Is it safe to assume that 0xe8 is really the start of an instruction?
>
> What if instead you are looking at a modrm or sib for a rip-relative read?
> It may not match in this case (I'm rusty at x86 and would have to look
> at an AMD or Intel manual to know) but your should check this and of
> course for the other encodings below.
>
> Also, might you have an R_X86_64_PC32 in data and so be looking at the
> high byte of the previous word?
>
>> +
>> +        // jmp
>> +        if (r_offset >= 1
>> +            && view[r_offset - 1] == 0xe9)
>> +          return false;
>> +
>> +        // jo/jno/jb/jnb/je/jne/jna/ja/js/jns/jp/jnp/jl/jge/jle/jg
>> +        if (r_offset >= 2
>> +            && view[r_offset - 2] == 0x0f
>> +            && view[r_offset - 1] >= 0x80
>> +            && view[r_offset - 1] <= 0x8f)
>> +          return false;
>> +
>> +        // Be conservative and treat all others as function pointers.
>> +        return true;
>> +      }
>>      }
>>    return false;
>>  }
>
> --
> Alan Modra
> Australia Development Lab, IBM


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]